diff --git a/sdk/perfetto.cc b/sdk/perfetto.cc
new file mode 100644
index 0000000..408da3c
--- /dev/null
+++ b/sdk/perfetto.cc
@@ -0,0 +1,69923 @@
+// 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
+#if !defined(GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER)
+#define GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
+#endif
+#if !defined(GOOGLE_PROTOBUF_NO_RTTI)
+#define GOOGLE_PROTOBUF_NO_RTTI
+#endif
+#include "perfetto.h"
+// 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 InstallCtrCHandler(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 InstallCtrCHandler(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/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_
+
+// 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.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// Windows.h typedefs HANDLE to void*. We use void* here to avoid leaking
+// Windows.h through our headers.
+using PlatformHandle = void*;
+
+// 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;
+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_
+// 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 PERFETTO_EXPORT 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 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_
+// gen_amalgamated begin header: include/perfetto/ext/base/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_EXT_BASE_UTILS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include <atomic>
+#include <string>
+
+#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
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+using uid_t = unsigned int;
+#if !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
+using pid_t = unsigned int;
+#endif
+#if defined(_WIN64)
+using ssize_t = int64_t;
+#else
+using ssize_t = long;
+#endif
+#endif
+
+namespace perfetto {
+namespace base {
+
+constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
+constexpr pid_t kInvalidPid = static_cast<pid_t>(-1);
+
+// Do not add new usages of kPageSize, consider using GetSysPageSize() below.
+// TODO(primiano): over time the semantic of kPageSize became too ambiguous.
+// Strictly speaking, this constant is incorrect on some new devices where the
+// page size can be 16K (e.g., crbug.com/1116576). Unfortunately too much code
+// ended up depending on kPageSize for purposes that are not strictly related
+// with the kernel's mm subsystem.
+constexpr size_t kPageSize = 4096;
+
+// Returns the system's page size. Use this when dealing with mmap, madvise and
+// similar mm-related syscalls.
+uint32_t GetSysPageSize();
+
+template <typename T>
+constexpr size_t ArraySize(const T& array) {
+  return sizeof(array) / sizeof(array[0]);
+}
+
+// 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).
+template <size_t alignment>
+constexpr size_t AlignUp(size_t size) {
+  static_assert((alignment & (alignment - 1)) == 0, "alignment must be a pow2");
+  return (size + alignment - 1) & ~(alignment - 1);
+}
+
+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);
+
+// 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 and exit(0).
+// Child: redirects stdio onto /dev/null and chdirs into .
+void Daemonize();
+
+// 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();
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_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/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 = 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 = 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 <string>
+
+// 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).
+class PERFETTO_EXPORT 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(); }
+
+ private:
+  bool ok_ = false;
+  std::string message_;
+};
+
+// 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);
+
+// 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 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);
+
+}  // 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 <string>
+#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/status.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.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>
+#else
+#include <dirent.h>
+#include <unistd.h>
+#endif
+
+namespace perfetto {
+namespace base {
+namespace {
+constexpr size_t kBufSize = 2048;
+}  // namespace
+
+ssize_t Read(int fd, void* dst, size_t dst_size) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  return _read(fd, dst, static_cast<unsigned>(dst_size));
+#else
+  return PERFETTO_EINTR(read(fd, dst, dst_size));
+#endif
+}
+
+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)));
+    ssize_t wr = PERFETTO_EINTR(
+        write(fd, static_cast<const char*>(buf) + written, bytes_left));
+    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) {
+  PERFETTO_DCHECK((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;
+}
+
+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;
+    // We do not use a ScopedResource for the HANDLE from FindFirstFile because
+    // the invalid value INVALID_HANDLE_VALUE is not a constexpr under some
+    // compile configurations, and thus cannot be used as a template argument.
+    HANDLE hFind = FindFirstFileA(glob_path.c_str(), &ffd);
+    if (hFind == INVALID_HANDLE_VALUE) {
+      // For empty directories, there should be at least one entry '.'.
+      // If FindFirstFileA returns INVALID_HANDLE_VALUE, this means directory
+      // couldn't be accessed.
+      FindClose(hFind);
+      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 if (ffd.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) {
+        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));
+    FindClose(hFind);
+#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);
+}
+
+}  // 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
+/*
+ * 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/time.h"
+
+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{};
+
+}  // 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];
+
+  // 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) {
+      strncpy(log_msg, "[printf format error]", max_len);
+      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)
+      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.
+  char line_str[10];
+  size_t line_len =
+      static_cast<size_t>(snprintf(line_str, sizeof(line_str), "%d", line));
+
+  // 24 will be the width of the file.cc:line column in the log event.
+  char file_and_line[24];
+  size_t fname_len = strlen(fname);
+  size_t fname_max = sizeof(file_and_line) - line_len - 2;  // 2 = ':' + '\0'.
+  size_t fname_offset = fname_len <= fname_max ? 0 : fname_len - fname_max;
+  int len = snprintf(file_and_line, sizeof(file_and_line), "%s:%s",
+                     fname + fname_offset, line_str);
+  memset(&file_and_line[len], ' ', sizeof(file_and_line) - size_t(len));
+  file_and_line[sizeof(file_and_line) - 1] = '\0';
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  // Logcat has already timestamping, don't re-emit it.
+  __android_log_print(ANDROID_LOG_DEBUG + level, "perfetto", "%s %s",
+                      file_and_line, 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.
+  char timestamp[32];
+  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;
+  snprintf(timestamp, sizeof(timestamp), "[%03u.%03u] ", t_sec, t_ms);
+
+  if (use_colors) {
+    fprintf(stderr, "%s%s%s%s %s%s%s\n", kLightGray, timestamp, file_and_line,
+            kReset, color, log_msg, kReset);
+  } else {
+    fprintf(stderr, "%s%s %s\n", timestamp, file_and_line, log_msg);
+  }
+}
+
+}  // 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 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_
+// 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,
+                             unsigned long address,
+                             unsigned long size,
+                             const char* description);
+}
+
+#define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description)   \
+  AnnotateBenignRaceSized(__FILE__, __LINE__,                             \
+                          reinterpret_cast<unsigned long>(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) 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
+constexpr size_t RingBuffer::kCapacity;
+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_;
+
+constexpr uint16_t Record::kTypeMask;
+constexpr uint16_t Record::kTypeCounter;
+constexpr uint16_t Record::kTypeEvent;
+
+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)
+
+#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 <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>
+
+#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 > 0u);
+  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 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, this is to ensure that when using multiple
+// periodic tasks, they happen at the same time, minimizing wakeups.
+// 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.
+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;
+  };
+
+  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 {
+base::ScopedPlatformHandle CreateTimerFd(uint32_t period_ms) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    (PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && __ANDROID_API__ >= 19)
+  base::ScopedPlatformHandle tfd(
+      timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC | TFD_NONBLOCK));
+  // The initial phase, aligned on wall clock.
+  uint32_t phase_ms =
+      period_ms -
+      static_cast<uint32_t>(base::GetBootTimeNs().count() % period_ms);
+  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);
+  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 base::ScopedPlatformHandle();
+  return tfd;
+#else
+  base::ignore_result(period_ms);
+  return base::ScopedPlatformHandle();
+#endif
+}
+}  // namespace
+
+PeriodicTask::PeriodicTask(base::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_.period_ms);
+    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 =
+      args_.period_ms -
+      static_cast<uint32_t>(base::GetWallTimeMs().count() % args_.period_ms);
+  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(base::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 = base::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
+  }
+  // The repetition of the if() is to deal with the ResetTimerFd() case above.
+  if (!thiz->timer_fd_) {
+    thiz->PostNextTask();
+  }
+  // Create a copy of the task in the unlikely event that the task ends up
+  // up destroying the PeriodicTask object or calling Reset() on it. 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;
+  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>
+
+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;
+}
+
+}  // 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:
+  // Can take ownership of the string if passed via std::move(), e.g.:
+  // StringSplitter(std::move(str), '\n');
+  StringSplitter(std::string, char delimiter);
+
+  // 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);
+
+  // 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);
+
+  // 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_;
+};
+
+}  // 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)
+    : str_(std::move(str)), delimiter_(delimiter) {
+  // 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)
+    : delimiter_(delimiter) {
+  Initialize(str, size);
+}
+
+StringSplitter::StringSplitter(StringSplitter* outer, char delimiter)
+    : delimiter_(delimiter) {
+  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_)
+      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_)
+      return true;
+    break;
+  }
+  cur_ = nullptr;
+  cur_size_ = 0;
+  return false;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/string_utils.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/string_utils.h
+// gen_amalgamated begin header: include/perfetto/ext/base/optional.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_OPTIONAL_H_
+#define INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
+
+#include <functional>
+#include <type_traits>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+namespace base {
+
+// Specification:
+// http://en.cppreference.com/w/cpp/utility/optional/in_place_t
+struct in_place_t {};
+
+// Specification:
+// http://en.cppreference.com/w/cpp/utility/optional/nullopt_t
+struct nullopt_t {
+  constexpr explicit nullopt_t(int) {}
+};
+
+// Specification:
+// http://en.cppreference.com/w/cpp/utility/optional/in_place
+constexpr in_place_t in_place = {};
+
+// Specification:
+// http://en.cppreference.com/w/cpp/utility/optional/nullopt
+constexpr nullopt_t nullopt(0);
+
+// Forward declaration, which is referred by following helpers.
+template <typename T>
+class Optional;
+
+namespace internal {
+
+template <typename T, bool = std::is_trivially_destructible<T>::value>
+struct OptionalStorageBase {
+  // Initializing |empty_| here instead of using default member initializing
+  // to avoid errors in g++ 4.8.
+  constexpr OptionalStorageBase() : empty_('\0') {}
+
+  template <class... Args>
+  constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
+      : is_populated_(true), value_(std::forward<Args>(args)...) {}
+
+  // When T is not trivially destructible we must call its
+  // destructor before deallocating its memory.
+  // Note that this hides the (implicitly declared) move constructor, which
+  // would be used for constexpr move constructor in OptionalStorage<T>.
+  // It is needed iff T is trivially move constructible. However, the current
+  // is_trivially_{copy,move}_constructible implementation requires
+  // is_trivially_destructible (which looks a bug, cf:
+  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 and
+  // http://cplusplus.github.io/LWG/lwg-active.html#2116), so it is not
+  // necessary for this case at the moment. Please see also the destructor
+  // comment in "is_trivially_destructible = true" specialization below.
+  ~OptionalStorageBase() {
+    if (is_populated_)
+      value_.~T();
+  }
+
+  template <class... Args>
+  void Init(Args&&... args) {
+    PERFETTO_DCHECK(!is_populated_);
+    ::new (&value_) T(std::forward<Args>(args)...);
+    is_populated_ = true;
+  }
+
+  bool is_populated_ = false;
+  union {
+    // |empty_| exists so that the union will always be initialized, even when
+    // it doesn't contain a value. Union members must be initialized for the
+    // constructor to be 'constexpr'.
+    char empty_;
+    T value_;
+  };
+};
+
+template <typename T>
+struct OptionalStorageBase<T, true /* trivially destructible */> {
+  // Initializing |empty_| here instead of using default member initializing
+  // to avoid errors in g++ 4.8.
+  constexpr OptionalStorageBase() : empty_('\0') {}
+
+  template <class... Args>
+  constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
+      : is_populated_(true), value_(std::forward<Args>(args)...) {}
+
+  // When T is trivially destructible (i.e. its destructor does nothing) there
+  // is no need to call it. Implicitly defined destructor is trivial, because
+  // both members (bool and union containing only variants which are trivially
+  // destructible) are trivially destructible.
+  // Explicitly-defaulted destructor is also trivial, but do not use it here,
+  // because it hides the implicit move constructor. It is needed to implement
+  // constexpr move constructor in OptionalStorage iff T is trivially move
+  // constructible. Note that, if T is trivially move constructible, the move
+  // constructor of OptionalStorageBase<T> is also implicitly defined and it is
+  // trivially move constructor. If T is not trivially move constructible,
+  // "not declaring move constructor without destructor declaration" here means
+  // "delete move constructor", which works because any move constructor of
+  // OptionalStorage will not refer to it in that case.
+
+  template <class... Args>
+  void Init(Args&&... args) {
+    PERFETTO_DCHECK(!is_populated_);
+    ::new (&value_) T(std::forward<Args>(args)...);
+    is_populated_ = true;
+  }
+
+  bool is_populated_ = false;
+  union {
+    // |empty_| exists so that the union will always be initialized, even when
+    // it doesn't contain a value. Union members must be initialized for the
+    // constructor to be 'constexpr'.
+    char empty_;
+    T value_;
+  };
+};
+
+// Implement conditional constexpr copy and move constructors. These are
+// constexpr if is_trivially_{copy,move}_constructible<T>::value is true
+// respectively. If each is true, the corresponding constructor is defined as
+// "= default;", which generates a constexpr constructor (In this case,
+// the condition of constexpr-ness is satisfied because the base class also has
+// compiler generated constexpr {copy,move} constructors). Note that
+// placement-new is prohibited in constexpr.
+template <typename T, bool = std::is_trivially_copy_constructible<T>::value>
+struct OptionalStorage : OptionalStorageBase<T> {
+  // This is no trivially {copy,move} constructible case. Other cases are
+  // defined below as specializations.
+
+  // Accessing the members of template base class requires explicit
+  // declaration.
+  using OptionalStorageBase<T>::is_populated_;
+  using OptionalStorageBase<T>::value_;
+  using OptionalStorageBase<T>::Init;
+
+  // Inherit constructors (specifically, the in_place constructor).
+  using OptionalStorageBase<T>::OptionalStorageBase;
+
+  // User defined constructor deletes the default constructor.
+  // Define it explicitly.
+  OptionalStorage() = default;
+
+  OptionalStorage(const OptionalStorage& other) : OptionalStorageBase<T>() {
+    if (other.is_populated_)
+      Init(other.value_);
+  }
+
+  OptionalStorage(OptionalStorage&& other) noexcept(
+      std::is_nothrow_move_constructible<T>::value) {
+    if (other.is_populated_)
+      Init(std::move(other.value_));
+  }
+};
+
+template <typename T>
+struct OptionalStorage<T, true /* trivially copy constructible */>
+    : OptionalStorageBase<T> {
+  using OptionalStorageBase<T>::is_populated_;
+  using OptionalStorageBase<T>::value_;
+  using OptionalStorageBase<T>::Init;
+  using OptionalStorageBase<T>::OptionalStorageBase;
+
+  OptionalStorage() = default;
+  OptionalStorage(const OptionalStorage& other) = default;
+
+  OptionalStorage(OptionalStorage&& other) noexcept(
+      std::is_nothrow_move_constructible<T>::value) {
+    if (other.is_populated_)
+      Init(std::move(other.value_));
+  }
+};
+
+// Base class to support conditionally usable copy-/move- constructors
+// and assign operators.
+template <typename T>
+class OptionalBase {
+  // This class provides implementation rather than public API, so everything
+  // should be hidden. Often we use composition, but we cannot in this case
+  // because of C++ language restriction.
+ protected:
+  constexpr OptionalBase() = default;
+  constexpr OptionalBase(const OptionalBase& other) = default;
+  constexpr OptionalBase(OptionalBase&& other) = default;
+
+  template <class... Args>
+  constexpr explicit OptionalBase(in_place_t, Args&&... args)
+      : storage_(in_place, std::forward<Args>(args)...) {}
+
+  // Implementation of converting constructors.
+  template <typename U>
+  explicit OptionalBase(const OptionalBase<U>& other) {
+    if (other.storage_.is_populated_)
+      storage_.Init(other.storage_.value_);
+  }
+
+  template <typename U>
+  explicit OptionalBase(OptionalBase<U>&& other) {
+    if (other.storage_.is_populated_)
+      storage_.Init(std::move(other.storage_.value_));
+  }
+
+  ~OptionalBase() = default;
+
+  OptionalBase& operator=(const OptionalBase& other) {
+    CopyAssign(other);
+    return *this;
+  }
+
+  OptionalBase& operator=(OptionalBase&& other) noexcept(
+      std::is_nothrow_move_assignable<T>::value&&
+          std::is_nothrow_move_constructible<T>::value) {
+    MoveAssign(std::move(other));
+    return *this;
+  }
+
+  template <typename U>
+  void CopyAssign(const OptionalBase<U>& other) {
+    if (other.storage_.is_populated_)
+      InitOrAssign(other.storage_.value_);
+    else
+      FreeIfNeeded();
+  }
+
+  template <typename U>
+  void MoveAssign(OptionalBase<U>&& other) {
+    if (other.storage_.is_populated_)
+      InitOrAssign(std::move(other.storage_.value_));
+    else
+      FreeIfNeeded();
+  }
+
+  template <typename U>
+  void InitOrAssign(U&& value) {
+    if (storage_.is_populated_)
+      storage_.value_ = std::forward<U>(value);
+    else
+      storage_.Init(std::forward<U>(value));
+  }
+
+  void FreeIfNeeded() {
+    if (!storage_.is_populated_)
+      return;
+    storage_.value_.~T();
+    storage_.is_populated_ = false;
+  }
+
+  // For implementing conversion, allow access to other typed OptionalBase
+  // class.
+  template <typename U>
+  friend class OptionalBase;
+
+  OptionalStorage<T> storage_;
+};
+
+// The following {Copy,Move}{Constructible,Assignable} structs are helpers to
+// implement constructor/assign-operator overloading. Specifically, if T is
+// is not movable but copyable, Optional<T>'s move constructor should not
+// participate in overload resolution. This inheritance trick implements that.
+template <bool is_copy_constructible>
+struct CopyConstructible {};
+
+template <>
+struct CopyConstructible<false> {
+  constexpr CopyConstructible() = default;
+  constexpr CopyConstructible(const CopyConstructible&) = delete;
+  constexpr CopyConstructible(CopyConstructible&&) = default;
+  CopyConstructible& operator=(const CopyConstructible&) = default;
+  CopyConstructible& operator=(CopyConstructible&&) = default;
+};
+
+template <bool is_move_constructible>
+struct MoveConstructible {};
+
+template <>
+struct MoveConstructible<false> {
+  constexpr MoveConstructible() = default;
+  constexpr MoveConstructible(const MoveConstructible&) = default;
+  constexpr MoveConstructible(MoveConstructible&&) = delete;
+  MoveConstructible& operator=(const MoveConstructible&) = default;
+  MoveConstructible& operator=(MoveConstructible&&) = default;
+};
+
+template <bool is_copy_assignable>
+struct CopyAssignable {};
+
+template <>
+struct CopyAssignable<false> {
+  constexpr CopyAssignable() = default;
+  constexpr CopyAssignable(const CopyAssignable&) = default;
+  constexpr CopyAssignable(CopyAssignable&&) = default;
+  CopyAssignable& operator=(const CopyAssignable&) = delete;
+  CopyAssignable& operator=(CopyAssignable&&) = default;
+};
+
+template <bool is_move_assignable>
+struct MoveAssignable {};
+
+template <>
+struct MoveAssignable<false> {
+  constexpr MoveAssignable() = default;
+  constexpr MoveAssignable(const MoveAssignable&) = default;
+  constexpr MoveAssignable(MoveAssignable&&) = default;
+  MoveAssignable& operator=(const MoveAssignable&) = default;
+  MoveAssignable& operator=(MoveAssignable&&) = delete;
+};
+
+// Helper to conditionally enable converting constructors and assign operators.
+template <typename T, typename U>
+struct IsConvertibleFromOptional
+    : std::integral_constant<
+          bool,
+          std::is_constructible<T, Optional<U>&>::value ||
+              std::is_constructible<T, const Optional<U>&>::value ||
+              std::is_constructible<T, Optional<U>&&>::value ||
+              std::is_constructible<T, const Optional<U>&&>::value ||
+              std::is_convertible<Optional<U>&, T>::value ||
+              std::is_convertible<const Optional<U>&, T>::value ||
+              std::is_convertible<Optional<U>&&, T>::value ||
+              std::is_convertible<const Optional<U>&&, T>::value> {};
+
+template <typename T, typename U>
+struct IsAssignableFromOptional
+    : std::integral_constant<
+          bool,
+          IsConvertibleFromOptional<T, U>::value ||
+              std::is_assignable<T&, Optional<U>&>::value ||
+              std::is_assignable<T&, const Optional<U>&>::value ||
+              std::is_assignable<T&, Optional<U>&&>::value ||
+              std::is_assignable<T&, const Optional<U>&&>::value> {};
+
+// Forward compatibility for C++17.
+// Introduce one more deeper nested namespace to avoid leaking using std::swap.
+namespace swappable_impl {
+using std::swap;
+
+struct IsSwappableImpl {
+  // Tests if swap can be called. Check<T&>(0) returns true_type iff swap is
+  // available for T. Otherwise, Check's overload resolution falls back to
+  // Check(...) declared below thanks to SFINAE, so returns false_type.
+  template <typename T>
+  static auto Check(int)
+      -> decltype(swap(std::declval<T>(), std::declval<T>()), std::true_type());
+
+  template <typename T>
+  static std::false_type Check(...);
+};
+}  // namespace swappable_impl
+
+template <typename T>
+struct IsSwappable : decltype(swappable_impl::IsSwappableImpl::Check<T&>(0)) {};
+
+// Forward compatibility for C++20.
+template <typename T>
+using RemoveCvRefT =
+    typename std::remove_cv<typename std::remove_reference<T>::type>::type;
+
+}  // namespace internal
+
+// On Windows, by default, empty-base class optimization does not work,
+// which means even if the base class is empty struct, it still consumes one
+// byte for its body. __declspec(empty_bases) enables the optimization.
+// cf)
+// https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
+#define OPTIONAL_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
+#else
+#define OPTIONAL_DECLSPEC_EMPTY_BASES
+#endif
+
+// base::Optional is a Chromium version of the C++17 optional class:
+// std::optional documentation:
+// http://en.cppreference.com/w/cpp/utility/optional
+// Chromium documentation:
+// https://chromium.googlesource.com/chromium/src/+/master/docs/optional.md
+//
+// These are the differences between the specification and the implementation:
+// - Constructors do not use 'constexpr' as it is a C++14 extension.
+// - 'constexpr' might be missing in some places for reasons specified locally.
+// - No exceptions are thrown, because they are banned from Chromium.
+//   Marked noexcept for only move constructor and move assign operators.
+// - All the non-members are in the 'base' namespace instead of 'std'.
+//
+// Note that T cannot have a constructor T(Optional<T>) etc. Optional<T>
+// PERFETTO_CHECKs T's constructor (specifically via IsConvertibleFromOptional),
+// and in the PERFETTO_CHECK whether T can be constructible from Optional<T>,
+// which is recursive so it does not work. As of Feb 2018, std::optional C++17
+// implementation in both clang and gcc has same limitation. MSVC SFINAE looks
+// to have different behavior, but anyway it reports an error, too.
+//
+// This file is a modified version of optional.h from Chromium at revision
+// 5e71bd454e60511c1293c0c686544aaa76094424. The changes remove C++14/C++17
+// specific code and replace with C++11 counterparts.
+template <typename T>
+class OPTIONAL_DECLSPEC_EMPTY_BASES Optional
+    : public internal::OptionalBase<T>,
+      public internal::CopyConstructible<std::is_copy_constructible<T>::value>,
+      public internal::MoveConstructible<std::is_move_constructible<T>::value>,
+      public internal::CopyAssignable<std::is_copy_constructible<T>::value &&
+                                      std::is_copy_assignable<T>::value>,
+      public internal::MoveAssignable<std::is_move_constructible<T>::value &&
+                                      std::is_move_assignable<T>::value> {
+ public:
+#undef OPTIONAL_DECLSPEC_EMPTY_BASES
+  using value_type = T;
+
+  // Defer default/copy/move constructor implementation to OptionalBase.
+  constexpr Optional() = default;
+  constexpr Optional(const Optional& other) = default;
+  constexpr Optional(Optional&& other) noexcept(
+      std::is_nothrow_move_constructible<T>::value) = default;
+
+  constexpr Optional(nullopt_t) {}  // NOLINT(runtime/explicit)
+
+  // Converting copy constructor. "explicit" only if
+  // std::is_convertible<const U&, T>::value is false. It is implemented by
+  // declaring two almost same constructors, but that condition in enable_if_t
+  // is different, so that either one is chosen, thanks to SFINAE.
+  template <typename U,
+            typename std::enable_if<
+                std::is_constructible<T, const U&>::value &&
+                    !internal::IsConvertibleFromOptional<T, U>::value &&
+                    std::is_convertible<const U&, T>::value,
+                bool>::type = false>
+  Optional(const Optional<U>& other) : internal::OptionalBase<T>(other) {}
+
+  template <typename U,
+            typename std::enable_if<
+                std::is_constructible<T, const U&>::value &&
+                    !internal::IsConvertibleFromOptional<T, U>::value &&
+                    !std::is_convertible<const U&, T>::value,
+                bool>::type = false>
+  explicit Optional(const Optional<U>& other)
+      : internal::OptionalBase<T>(other) {}
+
+  // Converting move constructor. Similar to converting copy constructor,
+  // declaring two (explicit and non-explicit) constructors.
+  template <typename U,
+            typename std::enable_if<
+                std::is_constructible<T, U&&>::value &&
+                    !internal::IsConvertibleFromOptional<T, U>::value &&
+                    std::is_convertible<U&&, T>::value,
+                bool>::type = false>
+  Optional(Optional<U>&& other) : internal::OptionalBase<T>(std::move(other)) {}
+
+  template <typename U,
+            typename std::enable_if<
+                std::is_constructible<T, U&&>::value &&
+                    !internal::IsConvertibleFromOptional<T, U>::value &&
+                    !std::is_convertible<U&&, T>::value,
+                bool>::type = false>
+  explicit Optional(Optional<U>&& other)
+      : internal::OptionalBase<T>(std::move(other)) {}
+
+  template <class... Args>
+  constexpr explicit Optional(in_place_t, Args&&... args)
+      : internal::OptionalBase<T>(in_place, std::forward<Args>(args)...) {}
+
+  template <class U,
+            class... Args,
+            class = typename std::enable_if<
+                std::is_constructible<value_type,
+                                      std::initializer_list<U>&,
+                                      Args...>::value>::type>
+  constexpr explicit Optional(in_place_t,
+                              std::initializer_list<U> il,
+                              Args&&... args)
+      : internal::OptionalBase<T>(in_place, il, std::forward<Args>(args)...) {}
+
+  // Forward value constructor. Similar to converting constructors,
+  // conditionally explicit.
+  template <
+      typename U = value_type,
+      typename std::enable_if<
+          std::is_constructible<T, U&&>::value &&
+              !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
+              !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
+              std::is_convertible<U&&, T>::value,
+          bool>::type = false>
+  constexpr Optional(U&& value)
+      : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
+
+  template <
+      typename U = value_type,
+      typename std::enable_if<
+          std::is_constructible<T, U&&>::value &&
+              !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
+              !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
+              !std::is_convertible<U&&, T>::value,
+          bool>::type = false>
+  constexpr explicit Optional(U&& value)
+      : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
+
+  ~Optional() = default;
+
+  // Defer copy-/move- assign operator implementation to OptionalBase.
+  Optional& operator=(const Optional& other) = default;
+  Optional& operator=(Optional&& other) noexcept(
+      std::is_nothrow_move_assignable<T>::value&&
+          std::is_nothrow_move_constructible<T>::value) = default;
+
+  Optional& operator=(nullopt_t) {
+    FreeIfNeeded();
+    return *this;
+  }
+
+  // Perfect-forwarded assignment.
+  template <typename U>
+  typename std::enable_if<
+      !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
+          std::is_constructible<T, U>::value &&
+          std::is_assignable<T&, U>::value &&
+          (!std::is_scalar<T>::value ||
+           !std::is_same<typename std::decay<U>::type, T>::value),
+      Optional&>::type
+  operator=(U&& value) {
+    InitOrAssign(std::forward<U>(value));
+    return *this;
+  }
+
+  // Copy assign the state of other.
+  template <typename U>
+  typename std::enable_if<!internal::IsAssignableFromOptional<T, U>::value &&
+                              std::is_constructible<T, const U&>::value &&
+                              std::is_assignable<T&, const U&>::value,
+                          Optional&>::type
+  operator=(const Optional<U>& other) {
+    CopyAssign(other);
+    return *this;
+  }
+
+  // Move assign the state of other.
+  template <typename U>
+  typename std::enable_if<!internal::IsAssignableFromOptional<T, U>::value &&
+                              std::is_constructible<T, U>::value &&
+                              std::is_assignable<T&, U>::value,
+                          Optional&>::type
+  operator=(Optional<U>&& other) {
+    MoveAssign(std::move(other));
+    return *this;
+  }
+
+  const T* operator->() const {
+    PERFETTO_DCHECK(storage_.is_populated_);
+    return &storage_.value_;
+  }
+
+  T* operator->() {
+    PERFETTO_DCHECK(storage_.is_populated_);
+    return &storage_.value_;
+  }
+
+  const T& operator*() const& {
+    PERFETTO_DCHECK(storage_.is_populated_);
+    return storage_.value_;
+  }
+
+  T& operator*() & {
+    PERFETTO_DCHECK(storage_.is_populated_);
+    return storage_.value_;
+  }
+
+  const T&& operator*() const&& {
+    PERFETTO_DCHECK(storage_.is_populated_);
+    return std::move(storage_.value_);
+  }
+
+  T&& operator*() && {
+    PERFETTO_DCHECK(storage_.is_populated_);
+    return std::move(storage_.value_);
+  }
+
+  constexpr explicit operator bool() const { return storage_.is_populated_; }
+
+  constexpr bool has_value() const { return storage_.is_populated_; }
+
+  T& value() & {
+    PERFETTO_CHECK(storage_.is_populated_);
+    return storage_.value_;
+  }
+
+  const T& value() const& {
+    PERFETTO_CHECK(storage_.is_populated_);
+    return storage_.value_;
+  }
+
+  T&& value() && {
+    PERFETTO_CHECK(storage_.is_populated_);
+    return std::move(storage_.value_);
+  }
+
+  const T&& value() const&& {
+    PERFETTO_CHECK(storage_.is_populated_);
+    return std::move(storage_.value_);
+  }
+
+  template <class U>
+  constexpr T value_or(U&& default_value) const& {
+    static_assert(std::is_convertible<U, T>::value,
+                  "U must be convertible to T");
+    return storage_.is_populated_
+               ? storage_.value_
+               : static_cast<T>(std::forward<U>(default_value));
+  }
+
+  template <class U>
+  T value_or(U&& default_value) && {
+    static_assert(std::is_convertible<U, T>::value,
+                  "U must be convertible to T");
+    return storage_.is_populated_
+               ? std::move(storage_.value_)
+               : static_cast<T>(std::forward<U>(default_value));
+  }
+
+  void swap(Optional& other) {
+    if (!storage_.is_populated_ && !other.storage_.is_populated_)
+      return;
+
+    if (storage_.is_populated_ != other.storage_.is_populated_) {
+      if (storage_.is_populated_) {
+        other.storage_.Init(std::move(storage_.value_));
+        FreeIfNeeded();
+      } else {
+        storage_.Init(std::move(other.storage_.value_));
+        other.FreeIfNeeded();
+      }
+      return;
+    }
+
+    PERFETTO_DCHECK(storage_.is_populated_ && other.storage_.is_populated_);
+    using std::swap;
+    swap(**this, *other);
+  }
+
+  void reset() { FreeIfNeeded(); }
+
+  template <class... Args>
+  T& emplace(Args&&... args) {
+    FreeIfNeeded();
+    storage_.Init(std::forward<Args>(args)...);
+    return storage_.value_;
+  }
+
+  template <class U, class... Args>
+  typename std::enable_if<
+      std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value,
+      T&>::type
+  emplace(std::initializer_list<U> il, Args&&... args) {
+    FreeIfNeeded();
+    storage_.Init(il, std::forward<Args>(args)...);
+    return storage_.value_;
+  }
+
+ private:
+  // Accessing template base class's protected member needs explicit
+  // declaration to do so.
+  using internal::OptionalBase<T>::CopyAssign;
+  using internal::OptionalBase<T>::FreeIfNeeded;
+  using internal::OptionalBase<T>::InitOrAssign;
+  using internal::OptionalBase<T>::MoveAssign;
+  using internal::OptionalBase<T>::storage_;
+};
+
+// Here after defines comparation operators. The definition follows
+// http://en.cppreference.com/w/cpp/utility/optional/operator_cmp
+// while bool() casting is replaced by has_value() to meet the chromium
+// style guide.
+template <class T, class U>
+bool operator==(const Optional<T>& lhs, const Optional<U>& rhs) {
+  if (lhs.has_value() != rhs.has_value())
+    return false;
+  if (!lhs.has_value())
+    return true;
+  return *lhs == *rhs;
+}
+
+template <class T, class U>
+bool operator!=(const Optional<T>& lhs, const Optional<U>& rhs) {
+  if (lhs.has_value() != rhs.has_value())
+    return true;
+  if (!lhs.has_value())
+    return false;
+  return *lhs != *rhs;
+}
+
+template <class T, class U>
+bool operator<(const Optional<T>& lhs, const Optional<U>& rhs) {
+  if (!rhs.has_value())
+    return false;
+  if (!lhs.has_value())
+    return true;
+  return *lhs < *rhs;
+}
+
+template <class T, class U>
+bool operator<=(const Optional<T>& lhs, const Optional<U>& rhs) {
+  if (!lhs.has_value())
+    return true;
+  if (!rhs.has_value())
+    return false;
+  return *lhs <= *rhs;
+}
+
+template <class T, class U>
+bool operator>(const Optional<T>& lhs, const Optional<U>& rhs) {
+  if (!lhs.has_value())
+    return false;
+  if (!rhs.has_value())
+    return true;
+  return *lhs > *rhs;
+}
+
+template <class T, class U>
+bool operator>=(const Optional<T>& lhs, const Optional<U>& rhs) {
+  if (!rhs.has_value())
+    return true;
+  if (!lhs.has_value())
+    return false;
+  return *lhs >= *rhs;
+}
+
+template <class T>
+constexpr bool operator==(const Optional<T>& opt, nullopt_t) {
+  return !opt;
+}
+
+template <class T>
+constexpr bool operator==(nullopt_t, const Optional<T>& opt) {
+  return !opt;
+}
+
+template <class T>
+constexpr bool operator!=(const Optional<T>& opt, nullopt_t) {
+  return opt.has_value();
+}
+
+template <class T>
+constexpr bool operator!=(nullopt_t, const Optional<T>& opt) {
+  return opt.has_value();
+}
+
+template <class T>
+constexpr bool operator<(const Optional<T>&, nullopt_t) {
+  return false;
+}
+
+template <class T>
+constexpr bool operator<(nullopt_t, const Optional<T>& opt) {
+  return opt.has_value();
+}
+
+template <class T>
+constexpr bool operator<=(const Optional<T>& opt, nullopt_t) {
+  return !opt;
+}
+
+template <class T>
+constexpr bool operator<=(nullopt_t, const Optional<T>&) {
+  return true;
+}
+
+template <class T>
+constexpr bool operator>(const Optional<T>& opt, nullopt_t) {
+  return opt.has_value();
+}
+
+template <class T>
+constexpr bool operator>(nullopt_t, const Optional<T>&) {
+  return false;
+}
+
+template <class T>
+constexpr bool operator>=(const Optional<T>&, nullopt_t) {
+  return true;
+}
+
+template <class T>
+constexpr bool operator>=(nullopt_t, const Optional<T>& opt) {
+  return !opt;
+}
+
+template <class T, class U>
+constexpr bool operator==(const Optional<T>& opt, const U& value) {
+  return opt.has_value() ? *opt == value : false;
+}
+
+template <class T, class U>
+constexpr bool operator==(const U& value, const Optional<T>& opt) {
+  return opt.has_value() ? value == *opt : false;
+}
+
+template <class T, class U>
+constexpr bool operator!=(const Optional<T>& opt, const U& value) {
+  return opt.has_value() ? *opt != value : true;
+}
+
+template <class T, class U>
+constexpr bool operator!=(const U& value, const Optional<T>& opt) {
+  return opt.has_value() ? value != *opt : true;
+}
+
+template <class T, class U>
+constexpr bool operator<(const Optional<T>& opt, const U& value) {
+  return opt.has_value() ? *opt < value : true;
+}
+
+template <class T, class U>
+constexpr bool operator<(const U& value, const Optional<T>& opt) {
+  return opt.has_value() ? value < *opt : false;
+}
+
+template <class T, class U>
+constexpr bool operator<=(const Optional<T>& opt, const U& value) {
+  return opt.has_value() ? *opt <= value : true;
+}
+
+template <class T, class U>
+constexpr bool operator<=(const U& value, const Optional<T>& opt) {
+  return opt.has_value() ? value <= *opt : false;
+}
+
+template <class T, class U>
+constexpr bool operator>(const Optional<T>& opt, const U& value) {
+  return opt.has_value() ? *opt > value : false;
+}
+
+template <class T, class U>
+constexpr bool operator>(const U& value, const Optional<T>& opt) {
+  return opt.has_value() ? value > *opt : true;
+}
+
+template <class T, class U>
+constexpr bool operator>=(const Optional<T>& opt, const U& value) {
+  return opt.has_value() ? *opt >= value : false;
+}
+
+template <class T, class U>
+constexpr bool operator>=(const U& value, const Optional<T>& opt) {
+  return opt.has_value() ? value >= *opt : true;
+}
+
+template <class T>
+constexpr Optional<typename std::decay<T>::type> make_optional(T&& value) {
+  return Optional<typename std::decay<T>::type>(std::forward<T>(value));
+}
+
+template <class T, class... Args>
+constexpr Optional<T> make_optional(Args&&... args) {
+  return Optional<T>(in_place, std::forward<Args>(args)...);
+}
+
+template <class T, class U, class... Args>
+constexpr Optional<T> make_optional(std::initializer_list<U> il,
+                                    Args&&... args) {
+  return Optional<T>(in_place, il, std::forward<Args>(args)...);
+}
+
+// Partial specialization for a function template is not allowed. Also, it is
+// not allowed to add overload function to std namespace, while it is allowed
+// to specialize the template in std. Thus, swap() (kind of) overloading is
+// defined in base namespace, instead.
+template <class T>
+typename std::enable_if<std::is_move_constructible<T>::value &&
+                        internal::IsSwappable<T>::value>::type
+swap(Optional<T>& lhs, Optional<T>& rhs) {
+  lhs.swap(rhs);
+}
+
+}  // namespace base
+}  // namespace perfetto
+
+template <class T>
+struct std::hash<perfetto::base::Optional<T>> {
+  size_t operator()(const perfetto::base::Optional<T>& opt) const {
+    return opt == perfetto::base::nullopt ? 0 : std::hash<T>()(*opt);
+  }
+};
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_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 <type_traits>
+
+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 Hash {
+ public:
+  // Creates an empty hash object
+  Hash() {}
+
+  // 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));
+  }
+
+  // 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]);
+      result_ *= kFnv1a64Prime;
+    }
+  }
+
+  uint64_t digest() { return result_; }
+
+ private:
+  static constexpr uint64_t kFnv1a64OffsetBasis = 0xcbf29ce484222325;
+  static constexpr uint64_t kFnv1a64Prime = 0x100000001b3;
+
+  uint64_t result_ = kFnv1a64OffsetBasis;
+};
+
+}  // 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:
+  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) {
+    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) {
+    if (other.size() == 0)
+      return true;
+    if (size() == 0)
+      return false;
+    if (other.size() > size())
+      return false;
+    for (uint32_t i = 0; i < other.size(); ++i) {
+      if (at(i) != other.at(i))
+        return false;
+    }
+    return true;
+  }
+
+  std::string ToStdString() const {
+    return size_ == 0 ? "" : std::string(data_, size_);
+  }
+
+  uint64_t Hash() const {
+    base::Hash 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_
+/*
+ * 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 <stdlib.h>
+
+#include <cinttypes>
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
+// 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 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) ? base::make_optional(value) : base::nullopt;
+}
+
+inline 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) ? base::make_optional(value) : base::nullopt;
+}
+
+// Note: it saturates to 7fffffffffffffff if parsing a hex number >= 0x8000...
+inline 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) ? base::make_optional(value) : base::nullopt;
+}
+
+inline 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) ? base::make_optional(value) : base::nullopt;
+}
+
+double StrToD(const char* nptr, char** endptr);
+
+inline Optional<double> CStringToDouble(const char* s) {
+  char* endptr = nullptr;
+  double value = StrToD(s, &endptr);
+  Optional<double> result(base::nullopt);
+  if (*s != '\0' && *endptr == '\0')
+    result = value;
+  return result;
+}
+
+inline Optional<uint32_t> StringToUInt32(const std::string& s, int base = 10) {
+  return CStringToUInt32(s.c_str(), base);
+}
+
+inline Optional<int32_t> StringToInt32(const std::string& s, int base = 10) {
+  return CStringToInt32(s.c_str(), base);
+}
+
+inline Optional<uint64_t> StringToUInt64(const std::string& s, int base = 10) {
+  return CStringToUInt64(s.c_str(), base);
+}
+
+inline Optional<int64_t> StringToInt64(const std::string& s, int base = 10) {
+  return CStringToInt64(s.c_str(), base);
+}
+
+inline 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 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);
+std::string TrimLeading(const std::string& str);
+std::string Base64Encode(const void* raw, size_t size);
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+
+#include <locale.h>
+#include <string.h>
+#include <algorithm>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#include <xlocale.h>
+#endif
+
+#include <cinttypes>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+namespace base {
+namespace {
+constexpr char kBase64Table[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    "abcdefghijklmnopqrstuvwxyz0123456789+/";
+}
+
+// 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 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);
+  auto final_size = snprintf(&buf[0], max_size, "0x%02x", number);
+  PERFETTO_DCHECK(final_size >= 0);
+  buf.resize(static_cast<size_t>(final_size));  // 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);
+  auto final_size = snprintf(&buf[0], max_size, "%" PRIx64 "", number);
+  PERFETTO_DCHECK(final_size >= 0);
+  buf.resize(static_cast<size_t>(final_size));  // 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;
+}
+
+std::string TrimLeading(const std::string& str) {
+  size_t idx = str.find_first_not_of(' ');
+  return idx == std::string::npos ? str : str.substr(idx);
+}
+
+std::string Base64Encode(const void* raw, size_t size) {
+  // The following three cases are based on the tables in the example
+  // section in https://en.wikipedia.org/wiki/Base64. We process three
+  // input bytes at a time, emitting 4 output bytes at a time.
+  const uint8_t* ptr = static_cast<const uint8_t*>(raw);
+  size_t ii = 0;
+
+  std::string out;
+  out.reserve((size + 2) * 4 / 3);
+
+  // While possible, process three input bytes.
+  for (; ii + 3 <= size; ii += 3) {
+    uint32_t twentyfour_bits =
+        (uint32_t(ptr[ii]) << 16) | (uint32_t(ptr[ii + 1]) << 8) | ptr[ii + 2];
+    out.push_back(kBase64Table[(twentyfour_bits >> 18)]);
+    out.push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
+    out.push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
+    out.push_back(kBase64Table[twentyfour_bits & 0x3f]);
+  }
+  if (ii + 2 <= size) {  // Process two input bytes.
+    uint32_t twentyfour_bits =
+        (uint32_t(ptr[ii]) << 16) | (uint32_t(ptr[ii + 1]) << 8);
+    out.push_back(kBase64Table[(twentyfour_bits >> 18)]);
+    out.push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
+    out.push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
+    out.push_back('=');  // Emit padding.
+    return out;
+  }
+  if (ii + 1 <= size) {  // Process a single input byte.
+    uint32_t twentyfour_bits = (uint32_t(ptr[ii]) << 16);
+    out.push_back(kBase64Table[(twentyfour_bits >> 18)]);
+    out.push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
+    out.push_back('=');  // Emit padding.
+    out.push_back('=');  // Emit padding.
+  }
+  return out;
+}
+
+}  // 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 {
+
+// static
+constexpr size_t StringView::npos;
+
+}  // 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"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+namespace {
+std::string GetTempName() {
+  char name[] = "perfetto-XXXXXX";
+  PERFETTO_CHECK(_mktemp_s(name, sizeof(name)) == 0);
+  return name;
+}
+}  // namespace
+#endif
+
+namespace perfetto {
+namespace base {
+
+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_ = GetSysTempDir() + "\\" + GetTempName();
+  // 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_ = GetSysTempDir() + "\\" + GetTempName();
+  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/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.
+ */
+
+// 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"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#else
+#include <unistd.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+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() {
+  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);
+}
+
+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));
+}
+
+#else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+void SleepMicroseconds(unsigned interval_us) {
+  ::usleep(static_cast<useconds_t>(interval_us));
+}
+
+#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;
+}
+
+}  // 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"
+
+#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 <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>
+#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
+
+namespace {
+extern "C" {
+using MalloptType = void (*)(int, int);
+}
+}  // namespace
+#endif  // OS_ANDROID
+
+namespace perfetto {
+namespace base {
+
+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;
+  mallopt_fn(PERFETTO_M_PURGE, 0);
+#endif
+}
+
+uint32_t GetSysPageSize() {
+  ignore_result(kPageSize);  // Just to keep the amalgamated build happy.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  static std::atomic<uint32_t> page_size{0};
+  // This function might be called in hot paths. Avoid calling getpagesize() all
+  // the times, in many implementations getpagesize() calls sysconf() which is
+  // not cheap.
+  uint32_t cached_value = page_size.load(std::memory_order_relaxed);
+  if (PERFETTO_UNLIKELY(cached_value == 0)) {
+    cached_value = static_cast<uint32_t>(getpagesize());
+    page_size.store(cached_value, std::memory_order_relaxed);
+  }
+  return cached_value;
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  return static_cast<uint32_t>(vm_page_size);
+#else
+  return 4096;
+#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 Daemonize() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  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();
+      break;
+    }
+    default:
+      printf("%d\n", pid);
+      exit(0);
+  }
+#else
+  // Avoid -Wunreachable warnings.
+  if (reinterpret_cast<intptr_t>(&Daemonize) != 16)
+    PERFETTO_FATAL("--background is only supported on Linux/Android/Mac");
+#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;
+}
+
+}  // 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 <array>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
+
+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); }
+
+  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
+
+// See https://www.ietf.org/rfc/rfc4122.txt
+Uuid Uuidv4() {
+  static std::minstd_rand rng(static_cast<uint32_t>(GetBootTimeNs().count()));
+  Uuid uuid;
+  auto& data = *uuid.data();
+
+  for (size_t i = 0; i < 16; ++i)
+    data[i] = static_cast<uint8_t>(rng());
+
+  // version:
+  data[6] = (data[6] & 0x0f) | 0x40;
+  // clock_seq_hi_and_reserved:
+  data[8] = (data[8] & 0x3f) | 0x80;
+
+  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/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() "v19.0-e356c101b"
+#define PERFETTO_VERSION_SCM_REVISION() "e356c101b9adccd9927e9f10d4362e974b80ee5d"
+
+#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/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 {
+
+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*/) { 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 {
+
+// 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);
+  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/watchdog.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
+
+#include <fcntl.h>
+#include <signal.h>
+#include <stdint.h>
+
+#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/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;
+
+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;
+  exit_signal_.notify_one();
+  thread_.join();
+}
+
+Watchdog* Watchdog::GetInstance() {
+  static Watchdog* watchdog = new Watchdog(kDefaultPollingInterval);
+  return watchdog;
+}
+
+Watchdog::Timer Watchdog::CreateFatalTimer(uint32_t ms) {
+  if (!enabled_.load(std::memory_order_relaxed))
+    return Watchdog::Timer(0);
+
+  return Watchdog::Timer(ms);
+}
+
+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.
+    enabled_ = true;
+    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() {
+  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;
+  }
+
+  std::unique_lock<std::mutex> guard(mutex_);
+  for (;;) {
+    exit_signal_.wait_for(guard,
+                          std::chrono::milliseconds(polling_interval_ms_));
+    if (!enabled_)
+      return;
+
+    lseek(stat_fd.get(), 0, SEEK_SET);
+
+    ProcStat stat;
+    if (!ReadProcStat(stat_fd.get(), &stat)) {
+      return;
+    }
+
+    uint64_t cpu_time = stat.utime + stat.stime;
+    uint64_t rss_bytes =
+        static_cast<uint64_t>(stat.rss_pages) * base::GetSysPageSize();
+
+    CheckMemory(rss_bytes);
+    CheckCpu(cpu_time);
+  }
+}
+
+void Watchdog::CheckMemory(uint64_t rss_bytes) {
+  if (memory_limit_bytes_ == 0)
+    return;
+
+  // 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_);
+      kill(getpid(), SIGABRT);
+    }
+  }
+}
+
+void Watchdog::CheckCpu(uint64_t cpu_time) {
+  if (cpu_limit_percentage_ == 0)
+    return;
+
+  // 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_);
+      kill(getpid(), SIGABRT);
+    }
+  }
+}
+
+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(uint32_t ms) {
+  if (!ms)
+    return;  // No-op timer created when the watchdog is disabled.
+
+  struct sigevent sev = {};
+  timer_t timerid;
+  sev.sigev_notify = SIGEV_THREAD_ID;
+  sev._sigev_un._tid = base::GetThreadId();
+  sev.sigev_signo = SIGABRT;
+  PERFETTO_CHECK(timer_create(CLOCK_MONOTONIC, &sev, &timerid) != -1);
+  timerid_ = base::make_optional(timerid);
+  struct itimerspec its = {};
+  its.it_value.tv_sec = ms / 1000;
+  its.it_value.tv_nsec = 1000000L * (ms % 1000);
+  PERFETTO_CHECK(timer_settime(timerid_.value(), 0, &its, nullptr) != -1);
+}
+
+Watchdog::Timer::~Timer() {
+  if (timerid_) {
+    timer_delete(timerid_.value());
+  }
+}
+
+Watchdog::Timer::Timer(Timer&& other) noexcept {
+  timerid_ = std::move(other.timerid_);
+  other.timerid_ = base::nullopt;
+}
+
+}  // 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 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_
+// 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"
+
+#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] = {};
+  size_t sz = std::min(name.size(), static_cast<size_t>(15));
+  strncpy(buf, name.c_str(), sz);
+
+#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;
+}
+
+#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) 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/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
+    int ret = PERFETTO_EINTR(poll(
+        &poll_fds_[0], static_cast<nfds_t>(poll_fds_.size()), poll_timeout_ms));
+    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 <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/optional.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 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.
+  };
+
+  // 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.
+    base::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.
+    std::string input;
+
+    OutputMode stdout_mode = kInherit;
+    OutputMode stderr_mode = 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 ==
+  // 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 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();
+  void KillAtMostOnce();
+  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");
+
+  if (dup2(args->stdin_pipe_rd, STDIN_FILENO) == -1)
+    die("Failed to dup2(STDIN)");
+  close(args->stdin_pipe_rd);
+
+  switch (args->create_args->stdout_mode) {
+    case Subprocess::kInherit:
+      break;
+    case Subprocess::kDevNull: {
+      if (dup2(open("/dev/null", O_RDWR), STDOUT_FILENO) == -1)
+        die("Failed to dup2(STDOUT)");
+      break;
+    }
+    case Subprocess::kBuffer:
+      if (dup2(args->stdouterr_pipe_wr, STDOUT_FILENO) == -1)
+        die("Failed to dup2(STDOUT)");
+      break;
+    case Subprocess::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::kInherit:
+      break;
+    case Subprocess::kDevNull: {
+      if (dup2(open("/dev/null", O_RDWR), STDERR_FILENO) == -1)
+        die("Failed to dup2(STDERR)");
+      break;
+    }
+    case Subprocess::kBuffer:
+      if (dup2(args->stdouterr_pipe_wr, STDERR_FILENO) == -1)
+        die("Failed to dup2(STDERR)");
+      break;
+    case Subprocess::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.
+  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);
+
+  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 == kBuffer || args.stdout_mode == kBuffer) {
+    s_->stdouterr_pipe = Pipe::Create();
+    PERFETTO_CHECK(
+        ::SetHandleInformation(*s_->stdouterr_pipe.wr, HANDLE_FLAG_INHERIT, 1));
+  }
+
+  ScopedPlatformHandle nul_handle;
+  if (args.stderr_mode == kDevNull || args.stdout_mode == kDevNull) {
+    nul_handle.reset(::CreateFileA("NUL", GENERIC_WRITE, 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 == kInherit) {
+    start_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
+  } else if (args.stderr_mode == kBuffer) {
+    start_info.hStdError = *s_->stdouterr_pipe.wr;
+  } else if (args.stderr_mode == kDevNull) {
+    start_info.hStdError = *nul_handle;
+  } else if (args.stderr_mode == 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 == kInherit) {
+    start_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
+  } else if (args.stdout_mode == kBuffer) {
+    start_info.hStdOutput = *s_->stdouterr_pipe.wr;
+  } else if (args.stdout_mode == kDevNull) {
+    start_info.hStdOutput = *nul_handle;
+  } else if (args.stdout_mode == kFd) {
+    PERFETTO_CHECK(
+        ::SetHandleInformation(*args.out_fd, HANDLE_FLAG_INHERIT, 1));
+    start_info.hStdOutput = *args.out_fd;
+  } else {
+    PERFETTO_CHECK(false);
+  }
+
+  start_info.hStdInput = *s_->stdin_pipe.rd;
+  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();
+  s_->stdin_thread = std::thread(&Subprocess::StdinThread, s, args.input);
+
+  if (args.stderr_mode == kBuffer || args.stdout_mode == 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 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 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/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 {
+
+#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;
+  size_already_written_ = 0;
+  nested_message_ = nullptr;
+  finalized_ = false;
+#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) {
+  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) {
+  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 (finalized_)
+    return size_;
+
+  if (nested_message_)
+    EndNestedMessage();
+
+  // Write the length of the nested message a posteriori, using a leading-zero
+  // redundant varint encoding.
+  if (size_field_) {
+    PERFETTO_DCHECK(!finalized_);
+    PERFETTO_DCHECK(size_ < proto_utils::kMaxMessageLength);
+    PERFETTO_DCHECK(size_ >= size_already_written_);
+    proto_utils::WriteRedundantVarInt(size_ - size_already_written_,
+                                      size_field_);
+    size_field_ = nullptr;
+  }
+
+  finalized_ = true;
+#if PERFETTO_DCHECK_IS_ON()
+  if (handle_)
+    handle_->reset_message();
+#endif
+
+  return size_;
+}
+
+Message* Message::BeginNestedMessageInternal(uint32_t 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();
+  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_.back().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_.back();
+  if (PERFETTO_UNLIKELY(block->entries >= Block::kCapacity)) {
+    blocks_.emplace_back();
+    block = &blocks_.back();
+  }
+  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_.back();
+  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 && blocks_.size() > 1) {
+    blocks_.pop_back();
+  }
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/message_handle.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_handle.h"
+
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+
+namespace protozero {
+
+MessageHandleBase::MessageHandleBase(Message* message) : message_(message) {
+#if PERFETTO_DCHECK_IS_ON()
+  generation_ = message_ ? message->generation_ : 0;
+  if (message_)
+    message_->set_handle(this);
+#endif
+}
+
+MessageHandleBase::~MessageHandleBase() {
+  if (message_) {
+#if PERFETTO_DCHECK_IS_ON()
+    PERFETTO_DCHECK(generation_ == message_->generation_);
+#endif
+    FinalizeMessage();
+  }
+}
+
+MessageHandleBase::MessageHandleBase(MessageHandleBase&& other) noexcept {
+  Move(std::move(other));
+}
+
+MessageHandleBase& MessageHandleBase::operator=(MessageHandleBase&& other) {
+  // 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;
+}
+
+void MessageHandleBase::Move(MessageHandleBase&& other) {
+  message_ = other.message_;
+  other.message_ = nullptr;
+#if PERFETTO_DCHECK_IS_ON()
+  if (message_) {
+    generation_ = message_->generation_;
+    message_->set_handle(this);
+  }
+#endif
+}
+
+}  // 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 {
+
+// static
+constexpr size_t PackedBufferBase::kOnStackStorageSize;
+
+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|.
+PERFETTO_ALWAYS_INLINE 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 > std::numeric_limits<uint16_t>::max())) {
+    PERFETTO_DLOG("Skipping field %" PRIu32 " because its id > 0xFFFF",
+                  field_id);
+    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(static_cast<uint16_t>(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;
+}
+
+PERFETTO_ALWAYS_INLINE
+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;
+    } else 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;
+
+    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.
+      if (PERFETTO_UNLIKELY(size_ >= capacity_)) {
+        ExpandHeapStorage();
+        // ExpandHeapStorage moves fields_ so we need to update the ptr to fld:
+        fld = &fields_[field_id];
+        PERFETTO_DCHECK(size_ < capacity_);
+      }
+      fields_[size_++] = *fld;
+      *fld = std::move(res.field);
+    }
+  }
+  read_ptr_ = res.next;
+}
+
+void TypedProtoDecoderBase::ExpandHeapStorage() {
+  uint32_t new_capacity = capacity_ * 2;
+  PERFETTO_CHECK(new_capacity > size_);
+  std::unique_ptr<Field[]> new_storage(new Field[new_capacity]);
+
+  static_assert(std::is_trivially_copyable<Field>::value,
+                "Field must be trivially copyable");
+  memcpy(&new_storage[0], fields_, sizeof(Field) * size_);
+
+  heap_storage_ = std::move(new_storage);
+  fields_ = &heap_storage_[0];
+  capacity_ = new_capacity;
+}
+
+}  // 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
+// 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 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_
+/*
+ * 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() {}
+
+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()
+  memset(begin, 0, size);
+#endif
+  return begin;
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/static_buffer.cc
+// 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 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_
+/*
+ * 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 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidEnergyConsumerDescriptor::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && energy_consumer_id_ == other.energy_consumer_id_
+   && ordinal_ == other.ordinal_
+   && type_ == other.type_
+   && 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 */:
+        field.get(&type_);
+        break;
+      case 4 /* name */:
+        field.get(&name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidEnergyConsumer::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidEnergyConsumer::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidEnergyConsumer::Serialize(::protozero::Message* msg) const {
+  // Field 1: energy_consumer_id
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, energy_consumer_id_);
+  }
+
+  // Field 2: ordinal
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, ordinal_);
+  }
+
+  // Field 3: type
+  if (_has_field_[3]) {
+    msg->AppendString(3, type_);
+  }
+
+  // Field 4: name
+  if (_has_field_[4]) {
+    msg->AppendString(4, name_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 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 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 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 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 CommitDataRequest_ChunksToMove : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPageFieldNumber = 1,
+    kChunkFieldNumber = 2,
+    kTargetBufferFieldNumber = 3,
+  };
+
+  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); }
+
+ private:
+  uint32_t page_{};
+  uint32_t chunk_{};
+  uint32_t target_buffer_{};
+
+  // 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_COMMIT_DATA_REQUEST_PROTO_CPP_H_
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && chunks_to_move_ == other.chunks_to_move_
+   && chunks_to_patch_ == other.chunks_to_patch_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CommitDataRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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]) {
+    msg->AppendVarInt(3, flush_request_id_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && target_buffer_ == other.target_buffer_
+   && writer_id_ == other.writer_id_
+   && chunk_id_ == other.chunk_id_
+   && patches_ == other.patches_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CommitDataRequest_ChunkToPatch::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CommitDataRequest_ChunkToPatch::Serialize(::protozero::Message* msg) const {
+  // Field 1: target_buffer
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, target_buffer_);
+  }
+
+  // Field 2: writer_id
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, writer_id_);
+  }
+
+  // Field 3: chunk_id
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, chunk_id_);
+  }
+
+  // Field 4: patches
+  for (auto& it : patches_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 5: has_more_patches
+  if (_has_field_[5]) {
+    msg->AppendTinyVarInt(5, has_more_patches_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && offset_ == other.offset_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CommitDataRequest_ChunkToPatch_Patch::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CommitDataRequest_ChunkToPatch_Patch::Serialize(::protozero::Message* msg) const {
+  // Field 1: offset
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, offset_);
+  }
+
+  // Field 2: data
+  if (_has_field_[2]) {
+    msg->AppendString(2, data_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && page_ == other.page_
+   && chunk_ == other.chunk_
+   && target_buffer_ == other.target_buffer_;
+}
+
+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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string CommitDataRequest_ChunksToMove::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CommitDataRequest_ChunksToMove::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CommitDataRequest_ChunksToMove::Serialize(::protozero::Message* msg) const {
+  // Field 1: page
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, page_);
+  }
+
+  // Field 2: chunk
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, chunk_);
+  }
+
+  // Field 3: target_buffer
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, target_buffer_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && name_ == other.name_
+   && will_notify_on_stop_ == other.will_notify_on_stop_
+   && will_notify_on_start_ == other.will_notify_on_start_
+   && handles_incremental_state_clear_ == other.handles_incremental_state_clear_
+   && gpu_counter_descriptor_ == other.gpu_counter_descriptor_
+   && track_event_descriptor_ == other.track_event_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 */:
+        field.get(&name_);
+        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 5 /* gpu_counter_descriptor */:
+        gpu_counter_descriptor_ = field.as_std_string();
+        break;
+      case 6 /* track_event_descriptor */:
+        track_event_descriptor_ = field.as_std_string();
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DataSourceDescriptor::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DataSourceDescriptor::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DataSourceDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    msg->AppendString(1, name_);
+  }
+
+  // Field 2: will_notify_on_stop
+  if (_has_field_[2]) {
+    msg->AppendTinyVarInt(2, will_notify_on_stop_);
+  }
+
+  // Field 3: will_notify_on_start
+  if (_has_field_[3]) {
+    msg->AppendTinyVarInt(3, will_notify_on_start_);
+  }
+
+  // Field 4: handles_incremental_state_clear
+  if (_has_field_[4]) {
+    msg->AppendTinyVarInt(4, handles_incremental_state_clear_);
+  }
+
+  // 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_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 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 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 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 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 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,
+    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_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_{};
+  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 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 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> OneofOptions::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void OneofOptions::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && name_ == other.name_
+   && 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 */:
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EnumValueDescriptorProto::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void EnumValueDescriptorProto::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    msg->AppendString(1, name_);
+  }
+
+  // Field 2: number
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, number_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && name_ == other.name_
+   && value_ == other.value_
+   && 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 */:
+        field.get(&name_);
+        break;
+      case 2 /* value */:
+        value_.emplace_back();
+        value_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* reserved_name */:
+        reserved_name_.emplace_back();
+        field.get(&reserved_name_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string EnumDescriptorProto::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EnumDescriptorProto::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void EnumDescriptorProto::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    msg->AppendString(1, name_);
+  }
+
+  // Field 2: value
+  for (auto& it : value_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 5: reserved_name
+  for (auto& it : reserved_name_) {
+    msg->AppendString(5, it);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && name_ == other.name_
+   && 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 */:
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> OneofDescriptorProto::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void OneofDescriptorProto::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    msg->AppendString(1, name_);
+  }
+
+  // Field 2: options
+  if (_has_field_[2]) {
+    (*options_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && name_ == other.name_
+   && number_ == other.number_
+   && label_ == other.label_
+   && type_ == other.type_
+   && type_name_ == other.type_name_
+   && extendee_ == other.extendee_
+   && default_value_ == other.default_value_
+   && 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 */:
+        field.get(&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 */:
+        field.get(&type_name_);
+        break;
+      case 2 /* extendee */:
+        field.get(&extendee_);
+        break;
+      case 7 /* default_value */:
+        field.get(&default_value_);
+        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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FieldDescriptorProto::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FieldDescriptorProto::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    msg->AppendString(1, name_);
+  }
+
+  // Field 3: number
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, number_);
+  }
+
+  // Field 4: label
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, label_);
+  }
+
+  // Field 5: type
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, type_);
+  }
+
+  // Field 6: type_name
+  if (_has_field_[6]) {
+    msg->AppendString(6, type_name_);
+  }
+
+  // Field 2: extendee
+  if (_has_field_[2]) {
+    msg->AppendString(2, extendee_);
+  }
+
+  // Field 7: default_value
+  if (_has_field_[7]) {
+    msg->AppendString(7, default_value_);
+  }
+
+  // Field 9: oneof_index
+  if (_has_field_[9]) {
+    msg->AppendVarInt(9, oneof_index_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && name_ == other.name_
+   && field_ == other.field_
+   && extension_ == other.extension_
+   && nested_type_ == other.nested_type_
+   && enum_type_ == other.enum_type_
+   && oneof_decl_ == other.oneof_decl_
+   && reserved_range_ == other.reserved_range_
+   && 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 */:
+        field.get(&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();
+        field.get(&reserved_name_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DescriptorProto::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DescriptorProto::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DescriptorProto::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    msg->AppendString(1, name_);
+  }
+
+  // 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_) {
+    msg->AppendString(10, it);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && start_ == other.start_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DescriptorProto_ReservedRange::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DescriptorProto_ReservedRange::Serialize(::protozero::Message* msg) const {
+  // Field 1: start
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, start_);
+  }
+
+  // Field 2: end
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, end_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && name_ == other.name_
+   && package_ == other.package_
+   && dependency_ == other.dependency_
+   && public_dependency_ == other.public_dependency_
+   && weak_dependency_ == other.weak_dependency_
+   && message_type_ == other.message_type_
+   && enum_type_ == other.enum_type_
+   && 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 */:
+        field.get(&name_);
+        break;
+      case 2 /* package */:
+        field.get(&package_);
+        break;
+      case 3 /* dependency */:
+        dependency_.emplace_back();
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FileDescriptorProto::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FileDescriptorProto::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    msg->AppendString(1, name_);
+  }
+
+  // Field 2: package
+  if (_has_field_[2]) {
+    msg->AppendString(2, package_);
+  }
+
+  // Field 3: dependency
+  for (auto& it : dependency_) {
+    msg->AppendString(3, it);
+  }
+
+  // Field 10: public_dependency
+  for (auto& it : public_dependency_) {
+    msg->AppendVarInt(10, it);
+  }
+
+  // Field 11: weak_dependency
+  for (auto& it : weak_dependency_) {
+    msg->AppendVarInt(11, it);
+  }
+
+  // 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));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FileDescriptorSet::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && specs_ == other.specs_
+   && blocks_ == other.blocks_
+   && min_sampling_period_ns_ == other.min_sampling_period_ns_
+   && max_sampling_period_ns_ == other.max_sampling_period_ns_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GpuCounterDescriptor::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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]) {
+    msg->AppendVarInt(3, min_sampling_period_ns_);
+  }
+
+  // Field 4: max_sampling_period_ns
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, max_sampling_period_ns_);
+  }
+
+  // Field 5: supports_instrumented_sampling
+  if (_has_field_[5]) {
+    msg->AppendTinyVarInt(5, supports_instrumented_sampling_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && block_id_ == other.block_id_
+   && block_capacity_ == other.block_capacity_
+   && name_ == other.name_
+   && description_ == other.description_
+   && 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 */:
+        field.get(&name_);
+        break;
+      case 4 /* description */:
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GpuCounterDescriptor_GpuCounterBlock::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GpuCounterDescriptor_GpuCounterBlock::Serialize(::protozero::Message* msg) const {
+  // Field 1: block_id
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, block_id_);
+  }
+
+  // Field 2: block_capacity
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, block_capacity_);
+  }
+
+  // Field 3: name
+  if (_has_field_[3]) {
+    msg->AppendString(3, name_);
+  }
+
+  // Field 4: description
+  if (_has_field_[4]) {
+    msg->AppendString(4, description_);
+  }
+
+  // Field 5: counter_ids
+  for (auto& it : counter_ids_) {
+    msg->AppendVarInt(5, it);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && counter_id_ == other.counter_id_
+   && name_ == other.name_
+   && description_ == other.description_
+   && int_peak_value_ == other.int_peak_value_
+   && double_peak_value_ == other.double_peak_value_
+   && numerator_units_ == other.numerator_units_
+   && denominator_units_ == other.denominator_units_
+   && select_by_default_ == other.select_by_default_
+   && 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 */:
+        field.get(&name_);
+        break;
+      case 3 /* description */:
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GpuCounterDescriptor_GpuCounterSpec::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GpuCounterDescriptor_GpuCounterSpec::Serialize(::protozero::Message* msg) const {
+  // Field 1: counter_id
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, counter_id_);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    msg->AppendString(2, name_);
+  }
+
+  // Field 3: description
+  if (_has_field_[3]) {
+    msg->AppendString(3, description_);
+  }
+
+  // Field 5: int_peak_value
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, int_peak_value_);
+  }
+
+  // Field 6: double_peak_value
+  if (_has_field_[6]) {
+    msg->AppendFixed(6, double_peak_value_);
+  }
+
+  // Field 7: numerator_units
+  for (auto& it : numerator_units_) {
+    msg->AppendVarInt(7, it);
+  }
+
+  // Field 8: denominator_units
+  for (auto& it : denominator_units_) {
+    msg->AppendVarInt(8, it);
+  }
+
+  // Field 9: select_by_default
+  if (_has_field_[9]) {
+    msg->AppendTinyVarInt(9, select_by_default_);
+  }
+
+  // Field 10: groups
+  for (auto& it : groups_) {
+    msg->AppendVarInt(10, it);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && 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 */:
+        field.get(&name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string InterceptorDescriptor::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> InterceptorDescriptor::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void InterceptorDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    msg->AppendString(1, name_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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_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,
+};
+enum ObservableEvents_DataSourceInstanceState : int {
+  ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED = 1,
+  ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED = 2,
+};
+
+class PERFETTO_EXPORT ObservableEvents : public ::protozero::CppMessageObj {
+ public:
+  using DataSourceInstanceStateChange = ObservableEvents_DataSourceInstanceStateChange;
+  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_MIN = ObservableEvents_Type_TYPE_UNSPECIFIED;
+  static constexpr auto Type_MAX = ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED;
+  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,
+  };
+
+  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); }
+
+ private:
+  std::vector<ObservableEvents_DataSourceInstanceStateChange> instance_state_changes_;
+  bool all_data_sources_started_{};
+
+  // 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && instance_state_changes_ == other.instance_state_changes_
+   && all_data_sources_started_ == other.all_data_sources_started_;
+}
+
+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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ObservableEvents::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ObservableEvents::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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]) {
+    msg->AppendTinyVarInt(2, all_data_sources_started_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && producer_name_ == other.producer_name_
+   && data_source_name_ == other.data_source_name_
+   && 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 */:
+        field.get(&producer_name_);
+        break;
+      case 2 /* data_source_name */:
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ObservableEvents_DataSourceInstanceStateChange::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ObservableEvents_DataSourceInstanceStateChange::Serialize(::protozero::Message* msg) const {
+  // Field 1: producer_name
+  if (_has_field_[1]) {
+    msg->AppendString(1, producer_name_);
+  }
+
+  // Field 2: data_source_name
+  if (_has_field_[2]) {
+    msg->AppendString(2, data_source_name_);
+  }
+
+  // Field 3: state
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, state_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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;
+}  // 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_HW_CPU_CYCLES = 10,
+  PerfEvents_Counter_HW_INSTRUCTIONS = 11,
+};
+
+class PERFETTO_EXPORT 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 HW_CPU_CYCLES = PerfEvents_Counter_HW_CPU_CYCLES;
+  static constexpr auto HW_INSTRUCTIONS = PerfEvents_Counter_HW_INSTRUCTIONS;
+  static constexpr auto Counter_MIN = PerfEvents_Counter_UNKNOWN_COUNTER;
+  static constexpr auto Counter_MAX = PerfEvents_Counter_HW_INSTRUCTIONS;
+  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 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 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 PerfEvents_Timebase : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kFrequencyFieldNumber = 2,
+    kPeriodFieldNumber = 1,
+    kCounterFieldNumber = 4,
+    kTracepointFieldNumber = 3,
+    kRawEventFieldNumber = 5,
+    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_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_;
+  std::string name_{};
+
+  // 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_PERF_EVENTS_PROTO_CPP_H_
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEvents::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PerfEvents::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && type_ == other.type_
+   && config_ == other.config_
+   && config1_ == other.config1_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEvents_RawEvent::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PerfEvents_RawEvent::Serialize(::protozero::Message* msg) const {
+  // Field 1: type
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, type_);
+  }
+
+  // Field 2: config
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, config_);
+  }
+
+  // Field 3: config1
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, config1_);
+  }
+
+  // Field 4: config2
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, config2_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && name_ == other.name_
+   && 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 */:
+        field.get(&name_);
+        break;
+      case 2 /* filter */:
+        field.get(&filter_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PerfEvents_Tracepoint::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEvents_Tracepoint::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PerfEvents_Tracepoint::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    msg->AppendString(1, name_);
+  }
+
+  // Field 2: filter
+  if (_has_field_[2]) {
+    msg->AppendString(2, filter_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && frequency_ == other.frequency_
+   && period_ == other.period_
+   && counter_ == other.counter_
+   && tracepoint_ == other.tracepoint_
+   && raw_event_ == other.raw_event_
+   && 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 10 /* name */:
+        field.get(&name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PerfEvents_Timebase::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEvents_Timebase::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PerfEvents_Timebase::Serialize(::protozero::Message* msg) const {
+  // Field 2: frequency
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, frequency_);
+  }
+
+  // Field 1: period
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, period_);
+  }
+
+  // Field 4: counter
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, counter_);
+  }
+
+  // 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 10: name
+  if (_has_field_[10]) {
+    msg->AppendString(10, name_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 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_BufferStats;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT TraceStats : public ::protozero::CppMessageObj {
+ public:
+  using BufferStats = TraceStats_BufferStats;
+  using FilterStats = TraceStats_FilterStats;
+  enum FieldNumbers {
+    kBufferStatsFieldNumber = 1,
+    kProducersConnectedFieldNumber = 2,
+    kProducersSeenFieldNumber = 3,
+    kDataSourcesRegisteredFieldNumber = 4,
+    kDataSourcesSeenFieldNumber = 5,
+    kTracingSessionsFieldNumber = 6,
+    kTotalBuffersFieldNumber = 7,
+    kChunksDiscardedFieldNumber = 8,
+    kPatchesDiscardedFieldNumber = 9,
+    kInvalidPacketsFieldNumber = 10,
+    kFilterStatsFieldNumber = 11,
+  };
+
+  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();
+
+  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(); }
+
+ private:
+  std::vector<TraceStats_BufferStats> buffer_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_;
+
+  // 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 TraceStats_FilterStats : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kInputPacketsFieldNumber = 1,
+    kInputBytesFieldNumber = 2,
+    kOutputBytesFieldNumber = 3,
+    kErrorsFieldNumber = 4,
+  };
+
+  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); }
+
+ private:
+  uint64_t input_packets_{};
+  uint64_t input_bytes_{};
+  uint64_t output_bytes_{};
+  uint64_t errors_{};
+
+  // 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && buffer_stats_ == other.buffer_stats_
+   && producers_connected_ == other.producers_connected_
+   && producers_seen_ == other.producers_seen_
+   && data_sources_registered_ == other.data_sources_registered_
+   && data_sources_seen_ == other.data_sources_seen_
+   && tracing_sessions_ == other.tracing_sessions_
+   && total_buffers_ == other.total_buffers_
+   && chunks_discarded_ == other.chunks_discarded_
+   && patches_discarded_ == other.patches_discarded_
+   && invalid_packets_ == other.invalid_packets_
+   && filter_stats_ == other.filter_stats_;
+}
+
+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(); }
+bool TraceStats::ParseFromArray(const void* raw, size_t size) {
+  buffer_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 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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceStats::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceStats::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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 2: producers_connected
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, producers_connected_);
+  }
+
+  // Field 3: producers_seen
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, producers_seen_);
+  }
+
+  // Field 4: data_sources_registered
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, data_sources_registered_);
+  }
+
+  // Field 5: data_sources_seen
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, data_sources_seen_);
+  }
+
+  // Field 6: tracing_sessions
+  if (_has_field_[6]) {
+    msg->AppendVarInt(6, tracing_sessions_);
+  }
+
+  // Field 7: total_buffers
+  if (_has_field_[7]) {
+    msg->AppendVarInt(7, total_buffers_);
+  }
+
+  // Field 8: chunks_discarded
+  if (_has_field_[8]) {
+    msg->AppendVarInt(8, chunks_discarded_);
+  }
+
+  // Field 9: patches_discarded
+  if (_has_field_[9]) {
+    msg->AppendVarInt(9, patches_discarded_);
+  }
+
+  // Field 10: invalid_packets
+  if (_has_field_[10]) {
+    msg->AppendVarInt(10, invalid_packets_);
+  }
+
+  // Field 11: filter_stats
+  if (_has_field_[11]) {
+    (*filter_stats_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && input_packets_ == other.input_packets_
+   && input_bytes_ == other.input_bytes_
+   && output_bytes_ == other.output_bytes_
+   && errors_ == other.errors_;
+}
+
+bool TraceStats_FilterStats::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 /* 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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceStats_FilterStats::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceStats_FilterStats::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceStats_FilterStats::Serialize(::protozero::Message* msg) const {
+  // Field 1: input_packets
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, input_packets_);
+  }
+
+  // Field 2: input_bytes
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, input_bytes_);
+  }
+
+  // Field 3: output_bytes
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, output_bytes_);
+  }
+
+  // Field 4: errors
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, errors_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && buffer_size_ == other.buffer_size_
+   && bytes_written_ == other.bytes_written_
+   && bytes_overwritten_ == other.bytes_overwritten_
+   && bytes_read_ == other.bytes_read_
+   && padding_bytes_written_ == other.padding_bytes_written_
+   && padding_bytes_cleared_ == other.padding_bytes_cleared_
+   && chunks_written_ == other.chunks_written_
+   && chunks_rewritten_ == other.chunks_rewritten_
+   && chunks_overwritten_ == other.chunks_overwritten_
+   && chunks_discarded_ == other.chunks_discarded_
+   && chunks_read_ == other.chunks_read_
+   && chunks_committed_out_of_order_ == other.chunks_committed_out_of_order_
+   && write_wrap_count_ == other.write_wrap_count_
+   && patches_succeeded_ == other.patches_succeeded_
+   && patches_failed_ == other.patches_failed_
+   && readaheads_succeeded_ == other.readaheads_succeeded_
+   && readaheads_failed_ == other.readaheads_failed_
+   && abi_violations_ == other.abi_violations_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceStats_BufferStats::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceStats_BufferStats::Serialize(::protozero::Message* msg) const {
+  // Field 12: buffer_size
+  if (_has_field_[12]) {
+    msg->AppendVarInt(12, buffer_size_);
+  }
+
+  // Field 1: bytes_written
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, bytes_written_);
+  }
+
+  // Field 13: bytes_overwritten
+  if (_has_field_[13]) {
+    msg->AppendVarInt(13, bytes_overwritten_);
+  }
+
+  // Field 14: bytes_read
+  if (_has_field_[14]) {
+    msg->AppendVarInt(14, bytes_read_);
+  }
+
+  // Field 15: padding_bytes_written
+  if (_has_field_[15]) {
+    msg->AppendVarInt(15, padding_bytes_written_);
+  }
+
+  // Field 16: padding_bytes_cleared
+  if (_has_field_[16]) {
+    msg->AppendVarInt(16, padding_bytes_cleared_);
+  }
+
+  // Field 2: chunks_written
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, chunks_written_);
+  }
+
+  // Field 10: chunks_rewritten
+  if (_has_field_[10]) {
+    msg->AppendVarInt(10, chunks_rewritten_);
+  }
+
+  // Field 3: chunks_overwritten
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, chunks_overwritten_);
+  }
+
+  // Field 18: chunks_discarded
+  if (_has_field_[18]) {
+    msg->AppendVarInt(18, chunks_discarded_);
+  }
+
+  // Field 17: chunks_read
+  if (_has_field_[17]) {
+    msg->AppendVarInt(17, chunks_read_);
+  }
+
+  // Field 11: chunks_committed_out_of_order
+  if (_has_field_[11]) {
+    msg->AppendVarInt(11, chunks_committed_out_of_order_);
+  }
+
+  // Field 4: write_wrap_count
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, write_wrap_count_);
+  }
+
+  // Field 5: patches_succeeded
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, patches_succeeded_);
+  }
+
+  // Field 6: patches_failed
+  if (_has_field_[6]) {
+    msg->AppendVarInt(6, patches_failed_);
+  }
+
+  // Field 7: readaheads_succeeded
+  if (_has_field_[7]) {
+    msg->AppendVarInt(7, readaheads_succeeded_);
+  }
+
+  // Field 8: readaheads_failed
+  if (_has_field_[8]) {
+    msg->AppendVarInt(8, readaheads_failed_);
+  }
+
+  // Field 9: abi_violations
+  if (_has_field_[9]) {
+    msg->AppendVarInt(9, abi_violations_);
+  }
+
+  // Field 19: trace_writer_packet_loss
+  if (_has_field_[19]) {
+    msg->AppendVarInt(19, trace_writer_packet_loss_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 TracingServiceCapabilities : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kHasQueryCapabilitiesFieldNumber = 1,
+    kObservableEventsFieldNumber = 2,
+    kHasTraceConfigOutputPathFieldNumber = 3,
+  };
+
+  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); }
+
+ private:
+  bool has_query_capabilities_{};
+  std::vector<ObservableEvents_Type> observable_events_;
+  bool has_trace_config_output_path_{};
+
+  // 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_TRACING_SERVICE_CAPABILITIES_PROTO_CPP_H_
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && has_query_capabilities_ == other.has_query_capabilities_
+   && observable_events_ == other.observable_events_
+   && has_trace_config_output_path_ == other.has_trace_config_output_path_;
+}
+
+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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TracingServiceCapabilities::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TracingServiceCapabilities::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TracingServiceCapabilities::Serialize(::protozero::Message* msg) const {
+  // Field 1: has_query_capabilities
+  if (_has_field_[1]) {
+    msg->AppendTinyVarInt(1, has_query_capabilities_);
+  }
+
+  // Field 2: observable_events
+  for (auto& it : observable_events_) {
+    msg->AppendVarInt(2, it);
+  }
+
+  // Field 3: has_trace_config_output_path
+  if (_has_field_[3]) {
+    msg->AppendTinyVarInt(3, has_trace_config_output_path_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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_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 TracingServiceState : public ::protozero::CppMessageObj {
+ public:
+  using Producer = TracingServiceState_Producer;
+  using DataSource = TracingServiceState_DataSource;
+  enum FieldNumbers {
+    kProducersFieldNumber = 1,
+    kDataSourcesFieldNumber = 2,
+    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();
+
+  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_;
+  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<6> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT 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 TracingServiceState_Producer : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+    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_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 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<5> _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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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"
+
+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 unknown_fields_ == other.unknown_fields_
+   && producers_ == other.producers_
+   && data_sources_ == other.data_sources_
+   && num_sessions_ == other.num_sessions_
+   && num_sessions_started_ == other.num_sessions_started_
+   && 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(); }
+bool TracingServiceState::ParseFromArray(const void* raw, size_t size) {
+  producers_.clear();
+  data_sources_.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 3 /* num_sessions */:
+        field.get(&num_sessions_);
+        break;
+      case 4 /* num_sessions_started */:
+        field.get(&num_sessions_started_);
+        break;
+      case 5 /* tracing_service_version */:
+        field.get(&tracing_service_version_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TracingServiceState::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TracingServiceState::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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 3: num_sessions
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, num_sessions_);
+  }
+
+  // Field 4: num_sessions_started
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, num_sessions_started_);
+  }
+
+  // Field 5: tracing_service_version
+  if (_has_field_[5]) {
+    msg->AppendString(5, tracing_service_version_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && ds_descriptor_ == other.ds_descriptor_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TracingServiceState_DataSource::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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]) {
+    msg->AppendVarInt(2, producer_id_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && id_ == other.id_
+   && name_ == other.name_
+   && uid_ == other.uid_
+   && 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 */:
+        field.get(&name_);
+        break;
+      case 3 /* uid */:
+        field.get(&uid_);
+        break;
+      case 4 /* sdk_version */:
+        field.get(&sdk_version_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TracingServiceState_Producer::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TracingServiceState_Producer::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TracingServiceState_Producer::Serialize(::protozero::Message* msg) const {
+  // Field 1: id
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, id_);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    msg->AppendString(2, name_);
+  }
+
+  // Field 3: uid
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, uid_);
+  }
+
+  // Field 4: sdk_version
+  if (_has_field_[4]) {
+    msg->AppendString(4, sdk_version_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEventDescriptor::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && name_ == other.name_
+   && description_ == other.description_
+   && 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 */:
+        field.get(&name_);
+        break;
+      case 2 /* description */:
+        field.get(&description_);
+        break;
+      case 3 /* tags */:
+        tags_.emplace_back();
+        field.get(&tags_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TrackEventCategory::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEventCategory::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackEventCategory::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    msg->AppendString(1, name_);
+  }
+
+  // Field 2: description
+  if (_has_field_[2]) {
+    msg->AppendString(2, description_);
+  }
+
+  // Field 3: tags
+  for (auto& it : tags_) {
+    msg->AppendString(3, it);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && log_ids_ == other.log_ids_
+   && min_prio_ == other.min_prio_
+   && 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();
+        field.get(&filter_tags_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidLogConfig::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidLogConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidLogConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: log_ids
+  for (auto& it : log_ids_) {
+    msg->AppendVarInt(1, it);
+  }
+
+  // Field 3: min_prio
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, min_prio_);
+  }
+
+  // Field 4: filter_tags
+  for (auto& it : filter_tags_) {
+    msg->AppendString(4, it);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidPolledStateConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidPolledStateConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: poll_ms
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, poll_ms_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && 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();
+        field.get(&package_name_filter_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PackagesListConfig::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PackagesListConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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_) {
+    msg->AppendString(1, it);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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_CompactSchedConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT FtraceConfig : public ::protozero::CppMessageObj {
+ public:
+  using CompactSchedConfig = FtraceConfig_CompactSchedConfig;
+  enum FieldNumbers {
+    kFtraceEventsFieldNumber = 1,
+    kAtraceCategoriesFieldNumber = 2,
+    kAtraceAppsFieldNumber = 3,
+    kBufferSizeKbFieldNumber = 10,
+    kDrainPeriodMsFieldNumber = 11,
+    kCompactSchedFieldNumber = 12,
+    kSymbolizeKsymsFieldNumber = 13,
+    kInitializeKsymsSynchronouslyForTestingFieldNumber = 14,
+  };
+
+  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_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_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); }
+
+ 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_;
+  bool symbolize_ksyms_{};
+  bool initialize_ksyms_synchronously_for_testing_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<15> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && ftrace_events_ == other.ftrace_events_
+   && atrace_categories_ == other.atrace_categories_
+   && atrace_apps_ == other.atrace_apps_
+   && buffer_size_kb_ == other.buffer_size_kb_
+   && drain_period_ms_ == other.drain_period_ms_
+   && compact_sched_ == other.compact_sched_
+   && symbolize_ksyms_ == other.symbolize_ksyms_
+   && initialize_ksyms_synchronously_for_testing_ == other.initialize_ksyms_synchronously_for_testing_;
+}
+
+bool FtraceConfig::ParseFromArray(const void* raw, size_t size) {
+  ftrace_events_.clear();
+  atrace_categories_.clear();
+  atrace_apps_.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();
+        field.get(&ftrace_events_.back());
+        break;
+      case 2 /* atrace_categories */:
+        atrace_categories_.emplace_back();
+        field.get(&atrace_categories_.back());
+        break;
+      case 3 /* atrace_apps */:
+        atrace_apps_.emplace_back();
+        field.get(&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 13 /* symbolize_ksyms */:
+        field.get(&symbolize_ksyms_);
+        break;
+      case 14 /* initialize_ksyms_synchronously_for_testing */:
+        field.get(&initialize_ksyms_synchronously_for_testing_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FtraceConfig::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FtraceConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FtraceConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: ftrace_events
+  for (auto& it : ftrace_events_) {
+    msg->AppendString(1, it);
+  }
+
+  // Field 2: atrace_categories
+  for (auto& it : atrace_categories_) {
+    msg->AppendString(2, it);
+  }
+
+  // Field 3: atrace_apps
+  for (auto& it : atrace_apps_) {
+    msg->AppendString(3, it);
+  }
+
+  // Field 10: buffer_size_kb
+  if (_has_field_[10]) {
+    msg->AppendVarInt(10, buffer_size_kb_);
+  }
+
+  // Field 11: drain_period_ms
+  if (_has_field_[11]) {
+    msg->AppendVarInt(11, drain_period_ms_);
+  }
+
+  // Field 12: compact_sched
+  if (_has_field_[12]) {
+    (*compact_sched_).Serialize(msg->BeginNestedMessage<::protozero::Message>(12));
+  }
+
+  // Field 13: symbolize_ksyms
+  if (_has_field_[13]) {
+    msg->AppendTinyVarInt(13, symbolize_ksyms_);
+  }
+
+  // Field 14: initialize_ksyms_synchronously_for_testing
+  if (_has_field_[14]) {
+    msg->AppendTinyVarInt(14, initialize_ksyms_synchronously_for_testing_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FtraceConfig_CompactSchedConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FtraceConfig_CompactSchedConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: enabled
+  if (_has_field_[1]) {
+    msg->AppendTinyVarInt(1, enabled_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && counter_period_ns_ == other.counter_period_ns_
+   && counter_ids_ == other.counter_ids_
+   && instrumented_sampling_ == other.instrumented_sampling_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GpuCounterConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GpuCounterConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: counter_period_ns
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, counter_period_ns_);
+  }
+
+  // Field 2: counter_ids
+  for (auto& it : counter_ids_) {
+    msg->AppendVarInt(2, it);
+  }
+
+  // Field 3: instrumented_sampling
+  if (_has_field_[3]) {
+    msg->AppendTinyVarInt(3, instrumented_sampling_);
+  }
+
+  // Field 4: fix_gpu_clock
+  if (_has_field_[4]) {
+    msg->AppendTinyVarInt(4, fix_gpu_clock_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && track_driver_memory_usage_ == other.track_driver_memory_usage_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> VulkanMemoryConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void VulkanMemoryConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: track_driver_memory_usage
+  if (_has_field_[1]) {
+    msg->AppendTinyVarInt(1, track_driver_memory_usage_);
+  }
+
+  // Field 2: track_device_memory_usage
+  if (_has_field_[2]) {
+    msg->AppendTinyVarInt(2, track_device_memory_usage_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && scan_interval_ms_ == other.scan_interval_ms_
+   && scan_delay_ms_ == other.scan_delay_ms_
+   && scan_batch_size_ == other.scan_batch_size_
+   && do_not_scan_ == other.do_not_scan_
+   && scan_mount_points_ == other.scan_mount_points_
+   && 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();
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> InodeFileConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void InodeFileConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: scan_interval_ms
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, scan_interval_ms_);
+  }
+
+  // Field 2: scan_delay_ms
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, scan_delay_ms_);
+  }
+
+  // Field 3: scan_batch_size
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, scan_batch_size_);
+  }
+
+  // Field 4: do_not_scan
+  if (_has_field_[4]) {
+    msg->AppendTinyVarInt(4, do_not_scan_);
+  }
+
+  // Field 5: scan_mount_points
+  for (auto& it : scan_mount_points_) {
+    msg->AppendString(5, it);
+  }
+
+  // Field 6: mount_point_mapping
+  for (auto& it : mount_point_mapping_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && mountpoint_ == other.mountpoint_
+   && 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 */:
+        field.get(&mountpoint_);
+        break;
+      case 2 /* scan_roots */:
+        scan_roots_.emplace_back();
+        field.get(&scan_roots_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string InodeFileConfig_MountPointMappingEntry::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> InodeFileConfig_MountPointMappingEntry::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void InodeFileConfig_MountPointMappingEntry::Serialize(::protozero::Message* msg) const {
+  // Field 1: mountpoint
+  if (_has_field_[1]) {
+    msg->AppendString(1, mountpoint_);
+  }
+
+  // Field 2: scan_roots
+  for (auto& it : scan_roots_) {
+    msg->AppendString(2, it);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && output_ == other.output_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ConsoleConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ConsoleConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: output
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, output_);
+  }
+
+  // Field 2: enable_colors
+  if (_has_field_[2]) {
+    msg->AppendTinyVarInt(2, enable_colors_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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,
+};
+
+class PERFETTO_EXPORT 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 BatteryCounters_MIN = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED;
+  static constexpr auto BatteryCounters_MAX = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT_AVG;
+  enum FieldNumbers {
+    kBatteryPollMsFieldNumber = 1,
+    kBatteryCountersFieldNumber = 2,
+    kCollectPowerRailsFieldNumber = 3,
+    kCollectEnergyEstimationBreakdownFieldNumber = 4,
+  };
+
+  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); }
+
+ private:
+  uint32_t battery_poll_ms_{};
+  std::vector<AndroidPowerConfig_BatteryCounters> battery_counters_;
+  bool collect_power_rails_{};
+  bool collect_energy_estimation_breakdown_{};
+
+  // 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_POWER_ANDROID_POWER_CONFIG_PROTO_CPP_H_
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && battery_poll_ms_ == other.battery_poll_ms_
+   && battery_counters_ == other.battery_counters_
+   && collect_power_rails_ == other.collect_power_rails_
+   && collect_energy_estimation_breakdown_ == other.collect_energy_estimation_breakdown_;
+}
+
+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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidPowerConfig::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidPowerConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidPowerConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: battery_poll_ms
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, battery_poll_ms_);
+  }
+
+  // Field 2: battery_counters
+  for (auto& it : battery_counters_) {
+    msg->AppendVarInt(2, it);
+  }
+
+  // Field 3: collect_power_rails
+  if (_has_field_[3]) {
+    msg->AppendTinyVarInt(3, collect_power_rails_);
+  }
+
+  // Field 4: collect_energy_estimation_breakdown
+  if (_has_field_[4]) {
+    msg->AppendTinyVarInt(4, collect_energy_estimation_breakdown_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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,
+    kRecordThreadTimeInStateFieldNumber = 7,
+    kThreadTimeInStateCacheSizeFieldNumber = 8,
+  };
+
+  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_record_thread_time_in_state() const { return _has_field_[7]; }
+  bool record_thread_time_in_state() const { return record_thread_time_in_state_; }
+  void set_record_thread_time_in_state(bool value) { record_thread_time_in_state_ = value; _has_field_.set(7); }
+
+  bool has_thread_time_in_state_cache_size() const { return _has_field_[8]; }
+  uint32_t thread_time_in_state_cache_size() const { return thread_time_in_state_cache_size_; }
+  void set_thread_time_in_state_cache_size(uint32_t value) { thread_time_in_state_cache_size_ = value; _has_field_.set(8); }
+
+ 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 record_thread_time_in_state_{};
+  uint32_t thread_time_in_state_cache_size_{};
+
+  // 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_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_CPP_H_
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && quirks_ == other.quirks_
+   && scan_all_processes_on_start_ == other.scan_all_processes_on_start_
+   && record_thread_names_ == other.record_thread_names_
+   && proc_stats_poll_ms_ == other.proc_stats_poll_ms_
+   && proc_stats_cache_ttl_ms_ == other.proc_stats_cache_ttl_ms_
+   && record_thread_time_in_state_ == other.record_thread_time_in_state_
+   && thread_time_in_state_cache_size_ == other.thread_time_in_state_cache_size_;
+}
+
+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 7 /* record_thread_time_in_state */:
+        field.get(&record_thread_time_in_state_);
+        break;
+      case 8 /* thread_time_in_state_cache_size */:
+        field.get(&thread_time_in_state_cache_size_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ProcessStatsConfig::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ProcessStatsConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ProcessStatsConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: quirks
+  for (auto& it : quirks_) {
+    msg->AppendVarInt(1, it);
+  }
+
+  // Field 2: scan_all_processes_on_start
+  if (_has_field_[2]) {
+    msg->AppendTinyVarInt(2, scan_all_processes_on_start_);
+  }
+
+  // Field 3: record_thread_names
+  if (_has_field_[3]) {
+    msg->AppendTinyVarInt(3, record_thread_names_);
+  }
+
+  // Field 4: proc_stats_poll_ms
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, proc_stats_poll_ms_);
+  }
+
+  // Field 6: proc_stats_cache_ttl_ms
+  if (_has_field_[6]) {
+    msg->AppendVarInt(6, proc_stats_cache_ttl_ms_);
+  }
+
+  // Field 7: record_thread_time_in_state
+  if (_has_field_[7]) {
+    msg->AppendTinyVarInt(7, record_thread_time_in_state_);
+  }
+
+  // Field 8: thread_time_in_state_cache_size
+  if (_has_field_[8]) {
+    msg->AppendVarInt(8, thread_time_in_state_cache_size_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && sampling_interval_bytes_ == other.sampling_interval_bytes_
+   && adaptive_sampling_shmem_threshold_ == other.adaptive_sampling_shmem_threshold_
+   && adaptive_sampling_max_sampling_interval_bytes_ == other.adaptive_sampling_max_sampling_interval_bytes_
+   && process_cmdline_ == other.process_cmdline_
+   && pid_ == other.pid_
+   && target_installed_by_ == other.target_installed_by_
+   && heaps_ == other.heaps_
+   && exclude_heaps_ == other.exclude_heaps_
+   && stream_allocations_ == other.stream_allocations_
+   && heap_sampling_intervals_ == other.heap_sampling_intervals_
+   && all_heaps_ == other.all_heaps_
+   && all_ == other.all_
+   && min_anonymous_memory_kb_ == other.min_anonymous_memory_kb_
+   && max_heapprofd_memory_kb_ == other.max_heapprofd_memory_kb_
+   && max_heapprofd_cpu_secs_ == other.max_heapprofd_cpu_secs_
+   && skip_symbol_prefix_ == other.skip_symbol_prefix_
+   && continuous_dump_config_ == other.continuous_dump_config_
+   && shmem_size_bytes_ == other.shmem_size_bytes_
+   && block_client_ == other.block_client_
+   && block_client_timeout_us_ == other.block_client_timeout_us_
+   && no_startup_ == other.no_startup_
+   && no_running_ == other.no_running_
+   && dump_at_max_ == other.dump_at_max_
+   && disable_fork_teardown_ == other.disable_fork_teardown_
+   && 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();
+        field.get(&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();
+        field.get(&target_installed_by_.back());
+        break;
+      case 20 /* heaps */:
+        heaps_.emplace_back();
+        field.get(&heaps_.back());
+        break;
+      case 27 /* exclude_heaps */:
+        exclude_heaps_.emplace_back();
+        field.get(&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();
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> HeapprofdConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void HeapprofdConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: sampling_interval_bytes
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, sampling_interval_bytes_);
+  }
+
+  // Field 24: adaptive_sampling_shmem_threshold
+  if (_has_field_[24]) {
+    msg->AppendVarInt(24, adaptive_sampling_shmem_threshold_);
+  }
+
+  // Field 25: adaptive_sampling_max_sampling_interval_bytes
+  if (_has_field_[25]) {
+    msg->AppendVarInt(25, adaptive_sampling_max_sampling_interval_bytes_);
+  }
+
+  // Field 2: process_cmdline
+  for (auto& it : process_cmdline_) {
+    msg->AppendString(2, it);
+  }
+
+  // Field 4: pid
+  for (auto& it : pid_) {
+    msg->AppendVarInt(4, it);
+  }
+
+  // Field 26: target_installed_by
+  for (auto& it : target_installed_by_) {
+    msg->AppendString(26, it);
+  }
+
+  // Field 20: heaps
+  for (auto& it : heaps_) {
+    msg->AppendString(20, it);
+  }
+
+  // Field 27: exclude_heaps
+  for (auto& it : exclude_heaps_) {
+    msg->AppendString(27, it);
+  }
+
+  // Field 23: stream_allocations
+  if (_has_field_[23]) {
+    msg->AppendTinyVarInt(23, stream_allocations_);
+  }
+
+  // Field 22: heap_sampling_intervals
+  for (auto& it : heap_sampling_intervals_) {
+    msg->AppendVarInt(22, it);
+  }
+
+  // Field 21: all_heaps
+  if (_has_field_[21]) {
+    msg->AppendTinyVarInt(21, all_heaps_);
+  }
+
+  // Field 5: all
+  if (_has_field_[5]) {
+    msg->AppendTinyVarInt(5, all_);
+  }
+
+  // Field 15: min_anonymous_memory_kb
+  if (_has_field_[15]) {
+    msg->AppendVarInt(15, min_anonymous_memory_kb_);
+  }
+
+  // Field 16: max_heapprofd_memory_kb
+  if (_has_field_[16]) {
+    msg->AppendVarInt(16, max_heapprofd_memory_kb_);
+  }
+
+  // Field 17: max_heapprofd_cpu_secs
+  if (_has_field_[17]) {
+    msg->AppendVarInt(17, max_heapprofd_cpu_secs_);
+  }
+
+  // Field 7: skip_symbol_prefix
+  for (auto& it : skip_symbol_prefix_) {
+    msg->AppendString(7, it);
+  }
+
+  // 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]) {
+    msg->AppendVarInt(8, shmem_size_bytes_);
+  }
+
+  // Field 9: block_client
+  if (_has_field_[9]) {
+    msg->AppendTinyVarInt(9, block_client_);
+  }
+
+  // Field 14: block_client_timeout_us
+  if (_has_field_[14]) {
+    msg->AppendVarInt(14, block_client_timeout_us_);
+  }
+
+  // Field 10: no_startup
+  if (_has_field_[10]) {
+    msg->AppendTinyVarInt(10, no_startup_);
+  }
+
+  // Field 11: no_running
+  if (_has_field_[11]) {
+    msg->AppendTinyVarInt(11, no_running_);
+  }
+
+  // Field 13: dump_at_max
+  if (_has_field_[13]) {
+    msg->AppendTinyVarInt(13, dump_at_max_);
+  }
+
+  // Field 18: disable_fork_teardown
+  if (_has_field_[18]) {
+    msg->AppendTinyVarInt(18, disable_fork_teardown_);
+  }
+
+  // Field 19: disable_vfork_detection
+  if (_has_field_[19]) {
+    msg->AppendTinyVarInt(19, disable_vfork_detection_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && dump_phase_ms_ == other.dump_phase_ms_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> HeapprofdConfig_ContinuousDumpConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void HeapprofdConfig_ContinuousDumpConfig::Serialize(::protozero::Message* msg) const {
+  // Field 5: dump_phase_ms
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, dump_phase_ms_);
+  }
+
+  // Field 6: dump_interval_ms
+  if (_has_field_[6]) {
+    msg->AppendVarInt(6, dump_interval_ms_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 JavaHprofConfig_ContinuousDumpConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDumpPhaseMsFieldNumber = 1,
+    kDumpIntervalMsFieldNumber = 2,
+  };
+
+  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); }
+
+ 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<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_CPP_H_
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && process_cmdline_ == other.process_cmdline_
+   && pid_ == other.pid_
+   && target_installed_by_ == other.target_installed_by_
+   && continuous_dump_config_ == other.continuous_dump_config_
+   && min_anonymous_memory_kb_ == other.min_anonymous_memory_kb_
+   && dump_smaps_ == other.dump_smaps_
+   && 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();
+        field.get(&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();
+        field.get(&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();
+        field.get(&ignored_types_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string JavaHprofConfig::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> JavaHprofConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void JavaHprofConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: process_cmdline
+  for (auto& it : process_cmdline_) {
+    msg->AppendString(1, it);
+  }
+
+  // Field 2: pid
+  for (auto& it : pid_) {
+    msg->AppendVarInt(2, it);
+  }
+
+  // Field 7: target_installed_by
+  for (auto& it : target_installed_by_) {
+    msg->AppendString(7, it);
+  }
+
+  // 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]) {
+    msg->AppendVarInt(4, min_anonymous_memory_kb_);
+  }
+
+  // Field 5: dump_smaps
+  if (_has_field_[5]) {
+    msg->AppendTinyVarInt(5, dump_smaps_);
+  }
+
+  // Field 6: ignored_types
+  for (auto& it : ignored_types_) {
+    msg->AppendString(6, it);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && dump_phase_ms_ == other.dump_phase_ms_
+   && dump_interval_ms_ == other.dump_interval_ms_;
+}
+
+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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string JavaHprofConfig_ContinuousDumpConfig::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> JavaHprofConfig_ContinuousDumpConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void JavaHprofConfig_ContinuousDumpConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: dump_phase_ms
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, dump_phase_ms_);
+  }
+
+  // Field 2: dump_interval_ms
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, dump_interval_ms_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 PerfEvents_Counter : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT PerfEventConfig : public ::protozero::CppMessageObj {
+ public:
+  using CallstackSampling = PerfEventConfig_CallstackSampling;
+  using Scope = PerfEventConfig_Scope;
+  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 PerfEventConfig_CallstackSampling : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kScopeFieldNumber = 1,
+    kKernelFramesFieldNumber = 2,
+  };
+
+  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); }
+
+ private:
+  ::protozero::CopyablePtr<PerfEventConfig_Scope> scope_;
+  bool kernel_frames_{};
+
+  // 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 PerfEventConfig_Scope : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTargetPidFieldNumber = 1,
+    kTargetCmdlineFieldNumber = 2,
+    kExcludePidFieldNumber = 3,
+    kExcludeCmdlineFieldNumber = 4,
+    kAdditionalCmdlineCountFieldNumber = 5,
+  };
+
+  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); }
+
+ 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_{};
+
+  // 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_PROFILING_PERF_EVENT_CONFIG_PROTO_CPP_H_
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && timebase_ == other.timebase_
+   && callstack_sampling_ == other.callstack_sampling_
+   && ring_buffer_read_period_ms_ == other.ring_buffer_read_period_ms_
+   && ring_buffer_pages_ == other.ring_buffer_pages_
+   && max_enqueued_footprint_kb_ == other.max_enqueued_footprint_kb_
+   && max_daemon_memory_kb_ == other.max_daemon_memory_kb_
+   && remote_descriptor_timeout_ms_ == other.remote_descriptor_timeout_ms_
+   && unwind_state_clear_period_ms_ == other.unwind_state_clear_period_ms_
+   && target_installed_by_ == other.target_installed_by_
+   && all_cpus_ == other.all_cpus_
+   && sampling_frequency_ == other.sampling_frequency_
+   && kernel_frames_ == other.kernel_frames_
+   && target_pid_ == other.target_pid_
+   && target_cmdline_ == other.target_cmdline_
+   && exclude_pid_ == other.exclude_pid_
+   && exclude_cmdline_ == other.exclude_cmdline_
+   && 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();
+        field.get(&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();
+        field.get(&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();
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEventConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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]) {
+    msg->AppendVarInt(8, ring_buffer_read_period_ms_);
+  }
+
+  // Field 3: ring_buffer_pages
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, ring_buffer_pages_);
+  }
+
+  // Field 17: max_enqueued_footprint_kb
+  if (_has_field_[17]) {
+    msg->AppendVarInt(17, max_enqueued_footprint_kb_);
+  }
+
+  // Field 13: max_daemon_memory_kb
+  if (_has_field_[13]) {
+    msg->AppendVarInt(13, max_daemon_memory_kb_);
+  }
+
+  // Field 9: remote_descriptor_timeout_ms
+  if (_has_field_[9]) {
+    msg->AppendVarInt(9, remote_descriptor_timeout_ms_);
+  }
+
+  // Field 10: unwind_state_clear_period_ms
+  if (_has_field_[10]) {
+    msg->AppendVarInt(10, unwind_state_clear_period_ms_);
+  }
+
+  // Field 18: target_installed_by
+  for (auto& it : target_installed_by_) {
+    msg->AppendString(18, it);
+  }
+
+  // Field 1: all_cpus
+  if (_has_field_[1]) {
+    msg->AppendTinyVarInt(1, all_cpus_);
+  }
+
+  // Field 2: sampling_frequency
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, sampling_frequency_);
+  }
+
+  // Field 12: kernel_frames
+  if (_has_field_[12]) {
+    msg->AppendTinyVarInt(12, kernel_frames_);
+  }
+
+  // Field 4: target_pid
+  for (auto& it : target_pid_) {
+    msg->AppendVarInt(4, it);
+  }
+
+  // Field 5: target_cmdline
+  for (auto& it : target_cmdline_) {
+    msg->AppendString(5, it);
+  }
+
+  // Field 6: exclude_pid
+  for (auto& it : exclude_pid_) {
+    msg->AppendVarInt(6, it);
+  }
+
+  // Field 7: exclude_cmdline
+  for (auto& it : exclude_cmdline_) {
+    msg->AppendString(7, it);
+  }
+
+  // Field 11: additional_cmdline_count
+  if (_has_field_[11]) {
+    msg->AppendVarInt(11, additional_cmdline_count_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && scope_ == other.scope_
+   && kernel_frames_ == other.kernel_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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PerfEventConfig_CallstackSampling::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEventConfig_CallstackSampling::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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]) {
+    msg->AppendTinyVarInt(2, kernel_frames_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && target_pid_ == other.target_pid_
+   && target_cmdline_ == other.target_cmdline_
+   && exclude_pid_ == other.exclude_pid_
+   && exclude_cmdline_ == other.exclude_cmdline_
+   && additional_cmdline_count_ == other.additional_cmdline_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();
+        field.get(&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();
+        field.get(&exclude_cmdline_.back());
+        break;
+      case 5 /* additional_cmdline_count */:
+        field.get(&additional_cmdline_count_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PerfEventConfig_Scope::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEventConfig_Scope::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PerfEventConfig_Scope::Serialize(::protozero::Message* msg) const {
+  // Field 1: target_pid
+  for (auto& it : target_pid_) {
+    msg->AppendVarInt(1, it);
+  }
+
+  // Field 2: target_cmdline
+  for (auto& it : target_cmdline_) {
+    msg->AppendString(2, it);
+  }
+
+  // Field 3: exclude_pid
+  for (auto& it : exclude_pid_) {
+    msg->AppendVarInt(3, it);
+  }
+
+  // Field 4: exclude_cmdline
+  for (auto& it : exclude_cmdline_) {
+    msg->AppendString(4, it);
+  }
+
+  // Field 5: additional_cmdline_count
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, additional_cmdline_count_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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,
+  };
+
+  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); }
+
+ 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_{};
+
+  // 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_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_CPP_H_
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && meminfo_period_ms_ == other.meminfo_period_ms_
+   && meminfo_counters_ == other.meminfo_counters_
+   && vmstat_period_ms_ == other.vmstat_period_ms_
+   && vmstat_counters_ == other.vmstat_counters_
+   && stat_period_ms_ == other.stat_period_ms_
+   && stat_counters_ == other.stat_counters_
+   && devfreq_period_ms_ == other.devfreq_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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SysStatsConfig::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SysStatsConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SysStatsConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: meminfo_period_ms
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, meminfo_period_ms_);
+  }
+
+  // Field 2: meminfo_counters
+  for (auto& it : meminfo_counters_) {
+    msg->AppendVarInt(2, it);
+  }
+
+  // Field 3: vmstat_period_ms
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, vmstat_period_ms_);
+  }
+
+  // Field 4: vmstat_counters
+  for (auto& it : vmstat_counters_) {
+    msg->AppendVarInt(4, it);
+  }
+
+  // Field 5: stat_period_ms
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, stat_period_ms_);
+  }
+
+  // Field 6: stat_counters
+  for (auto& it : stat_counters_) {
+    msg->AppendVarInt(6, it);
+  }
+
+  // Field 7: devfreq_period_ms
+  if (_has_field_[7]) {
+    msg->AppendVarInt(7, devfreq_period_ms_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && disabled_categories_ == other.disabled_categories_
+   && enabled_categories_ == other.enabled_categories_
+   && disabled_tags_ == other.disabled_tags_
+   && enabled_tags_ == other.enabled_tags_;
+}
+
+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();
+        field.get(&disabled_categories_.back());
+        break;
+      case 2 /* enabled_categories */:
+        enabled_categories_.emplace_back();
+        field.get(&enabled_categories_.back());
+        break;
+      case 3 /* disabled_tags */:
+        disabled_tags_.emplace_back();
+        field.get(&disabled_tags_.back());
+        break;
+      case 4 /* enabled_tags */:
+        enabled_tags_.emplace_back();
+        field.get(&enabled_tags_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TrackEventConfig::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEventConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackEventConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: disabled_categories
+  for (auto& it : disabled_categories_) {
+    msg->AppendString(1, it);
+  }
+
+  // Field 2: enabled_categories
+  for (auto& it : enabled_categories_) {
+    msg->AppendString(2, it);
+  }
+
+  // Field 3: disabled_tags
+  for (auto& it : disabled_tags_) {
+    msg->AppendString(3, it);
+  }
+
+  // Field 4: enabled_tags
+  for (auto& it : enabled_tags_) {
+    msg->AppendString(4, it);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && trace_config_ == other.trace_config_
+   && privacy_filtering_enabled_ == other.privacy_filtering_enabled_
+   && convert_to_legacy_json_ == other.convert_to_legacy_json_
+   && client_priority_ == other.client_priority_
+   && 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 */:
+        field.get(&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 */:
+        field.get(&json_agent_label_filter_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeConfig::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_config
+  if (_has_field_[1]) {
+    msg->AppendString(1, trace_config_);
+  }
+
+  // Field 2: privacy_filtering_enabled
+  if (_has_field_[2]) {
+    msg->AppendTinyVarInt(2, privacy_filtering_enabled_);
+  }
+
+  // Field 3: convert_to_legacy_json
+  if (_has_field_[3]) {
+    msg->AppendTinyVarInt(3, convert_to_legacy_json_);
+  }
+
+  // Field 4: client_priority
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, client_priority_);
+  }
+
+  // Field 5: json_agent_label_filter
+  if (_has_field_[5]) {
+    msg->AppendString(5, json_agent_label_filter_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 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/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;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT 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); }
+
+  const std::string& console_config_raw() const { return console_config_; }
+  void set_console_config_raw(const std::string& raw) { console_config_ = raw; _has_field_.set(100); }
+
+ private:
+  std::string name_{};
+  std::string console_config_;  // [lazy=true]
+
+  // 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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/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 unknown_fields_ == other.unknown_fields_
+   && name_ == other.name_
+   && target_buffer_ == other.target_buffer_
+   && trace_duration_ms_ == other.trace_duration_ms_
+   && stop_timeout_ms_ == other.stop_timeout_ms_
+   && enable_extra_guardrails_ == other.enable_extra_guardrails_
+   && session_initiator_ == other.session_initiator_
+   && tracing_session_id_ == other.tracing_session_id_
+   && ftrace_config_ == other.ftrace_config_
+   && inode_file_config_ == other.inode_file_config_
+   && process_stats_config_ == other.process_stats_config_
+   && sys_stats_config_ == other.sys_stats_config_
+   && heapprofd_config_ == other.heapprofd_config_
+   && java_hprof_config_ == other.java_hprof_config_
+   && android_power_config_ == other.android_power_config_
+   && android_log_config_ == other.android_log_config_
+   && gpu_counter_config_ == other.gpu_counter_config_
+   && packages_list_config_ == other.packages_list_config_
+   && perf_event_config_ == other.perf_event_config_
+   && vulkan_memory_config_ == other.vulkan_memory_config_
+   && track_event_config_ == other.track_event_config_
+   && android_polled_state_config_ == other.android_polled_state_config_
+   && chrome_config_ == other.chrome_config_
+   && interceptor_config_ == other.interceptor_config_
+   && legacy_config_ == other.legacy_config_
+   && 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 */:
+        field.get(&name_);
+        break;
+      case 2 /* target_buffer */:
+        field.get(&target_buffer_);
+        break;
+      case 3 /* trace_duration_ms */:
+        field.get(&trace_duration_ms_);
+        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 */:
+        ftrace_config_ = field.as_std_string();
+        break;
+      case 102 /* inode_file_config */:
+        inode_file_config_ = field.as_std_string();
+        break;
+      case 103 /* process_stats_config */:
+        process_stats_config_ = field.as_std_string();
+        break;
+      case 104 /* sys_stats_config */:
+        sys_stats_config_ = field.as_std_string();
+        break;
+      case 105 /* heapprofd_config */:
+        heapprofd_config_ = field.as_std_string();
+        break;
+      case 110 /* java_hprof_config */:
+        java_hprof_config_ = field.as_std_string();
+        break;
+      case 106 /* android_power_config */:
+        android_power_config_ = field.as_std_string();
+        break;
+      case 107 /* android_log_config */:
+        android_log_config_ = field.as_std_string();
+        break;
+      case 108 /* gpu_counter_config */:
+        gpu_counter_config_ = field.as_std_string();
+        break;
+      case 109 /* packages_list_config */:
+        packages_list_config_ = field.as_std_string();
+        break;
+      case 111 /* perf_event_config */:
+        perf_event_config_ = field.as_std_string();
+        break;
+      case 112 /* vulkan_memory_config */:
+        vulkan_memory_config_ = field.as_std_string();
+        break;
+      case 113 /* track_event_config */:
+        track_event_config_ = field.as_std_string();
+        break;
+      case 114 /* android_polled_state_config */:
+        android_polled_state_config_ = field.as_std_string();
+        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 1000 /* legacy_config */:
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DataSourceConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DataSourceConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    msg->AppendString(1, name_);
+  }
+
+  // Field 2: target_buffer
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, target_buffer_);
+  }
+
+  // Field 3: trace_duration_ms
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, trace_duration_ms_);
+  }
+
+  // Field 7: stop_timeout_ms
+  if (_has_field_[7]) {
+    msg->AppendVarInt(7, stop_timeout_ms_);
+  }
+
+  // Field 6: enable_extra_guardrails
+  if (_has_field_[6]) {
+    msg->AppendTinyVarInt(6, enable_extra_guardrails_);
+  }
+
+  // Field 8: session_initiator
+  if (_has_field_[8]) {
+    msg->AppendVarInt(8, session_initiator_);
+  }
+
+  // Field 4: tracing_session_id
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, tracing_session_id_);
+  }
+
+  // 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 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 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 1000: legacy_config
+  if (_has_field_[1000]) {
+    msg->AppendString(1000, legacy_config_);
+  }
+
+  // Field 1001: for_testing
+  if (_has_field_[1001]) {
+    (*for_testing_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1001));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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/message.h"
+// gen_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"
+
+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 unknown_fields_ == other.unknown_fields_
+   && name_ == other.name_
+   && 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 */:
+        field.get(&name_);
+        break;
+      case 100 /* console_config */:
+        console_config_ = field.as_std_string();
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string InterceptorConfig::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> InterceptorConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void InterceptorConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    msg->AppendString(1, name_);
+  }
+
+  // Field 100: console_config
+  if (_has_field_[100]) {
+    msg->AppendString(100, console_config_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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_TraceFilter;
+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 ChromeConfig;
+class TraceConfig_BufferConfig;
+enum TraceConfig_LockdownModeOperation : int;
+enum TraceConfig_CompressionType : int;
+enum TraceConfig_StatsdLogging : int;
+enum TraceConfig_TriggerConfig_TriggerMode : int;
+enum BuiltinClock : int;
+enum DataSourceConfig_SessionInitiator : 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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/common/builtin_clock.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.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/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/chrome/chrome_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_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"
+
+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 unknown_fields_ == other.unknown_fields_
+   && trace_config_ == other.trace_config_
+   && shmem_size_kb_ == other.shmem_size_kb_
+   && shmem_page_size_kb_ == other.shmem_page_size_kb_
+   && num_processes_ == other.num_processes_
+   && num_threads_ == other.num_threads_
+   && max_events_ == other.max_events_
+   && nesting_ == other.nesting_
+   && steady_state_timings_ == other.steady_state_timings_
+   && burst_period_ms_ == other.burst_period_ms_
+   && burst_duration_ms_ == other.burst_duration_ms_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> StressTestConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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]) {
+    msg->AppendVarInt(2, shmem_size_kb_);
+  }
+
+  // Field 3: shmem_page_size_kb
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, shmem_page_size_kb_);
+  }
+
+  // Field 4: num_processes
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, num_processes_);
+  }
+
+  // Field 5: num_threads
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, num_threads_);
+  }
+
+  // Field 6: max_events
+  if (_has_field_[6]) {
+    msg->AppendVarInt(6, max_events_);
+  }
+
+  // Field 7: nesting
+  if (_has_field_[7]) {
+    msg->AppendVarInt(7, nesting_);
+  }
+
+  // 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]) {
+    msg->AppendVarInt(9, burst_period_ms_);
+  }
+
+  // Field 10: burst_duration_ms
+  if (_has_field_[10]) {
+    msg->AppendVarInt(10, burst_duration_ms_);
+  }
+
+  // Field 11: burst_timings
+  if (_has_field_[11]) {
+    (*burst_timings_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && payload_mean_ == other.payload_mean_
+   && payload_stddev_ == other.payload_stddev_
+   && rate_mean_ == other.rate_mean_
+   && rate_stddev_ == other.rate_stddev_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> StressTestConfig_WriterTiming::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void StressTestConfig_WriterTiming::Serialize(::protozero::Message* msg) const {
+  // Field 1: payload_mean
+  if (_has_field_[1]) {
+    msg->AppendFixed(1, payload_mean_);
+  }
+
+  // Field 2: payload_stddev
+  if (_has_field_[2]) {
+    msg->AppendFixed(2, payload_stddev_);
+  }
+
+  // Field 3: rate_mean
+  if (_has_field_[3]) {
+    msg->AppendFixed(3, rate_mean_);
+  }
+
+  // Field 4: rate_stddev
+  if (_has_field_[4]) {
+    msg->AppendFixed(4, rate_stddev_);
+  }
+
+  // Field 5: payload_write_time_ms
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, payload_write_time_ms_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && message_count_ == other.message_count_
+   && max_messages_per_second_ == other.max_messages_per_second_
+   && seed_ == other.seed_
+   && message_size_ == other.message_size_
+   && send_batch_on_register_ == other.send_batch_on_register_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TestConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TestConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: message_count
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, message_count_);
+  }
+
+  // Field 2: max_messages_per_second
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, max_messages_per_second_);
+  }
+
+  // Field 3: seed
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, seed_);
+  }
+
+  // Field 4: message_size
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, message_size_);
+  }
+
+  // Field 5: send_batch_on_register
+  if (_has_field_[5]) {
+    msg->AppendTinyVarInt(5, send_batch_on_register_);
+  }
+
+  // Field 6: dummy_fields
+  if (_has_field_[6]) {
+    (*dummy_fields_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && field_uint32_ == other.field_uint32_
+   && field_int32_ == other.field_int32_
+   && field_uint64_ == other.field_uint64_
+   && field_int64_ == other.field_int64_
+   && field_fixed64_ == other.field_fixed64_
+   && field_sfixed64_ == other.field_sfixed64_
+   && field_fixed32_ == other.field_fixed32_
+   && field_sfixed32_ == other.field_sfixed32_
+   && field_double_ == other.field_double_
+   && field_float_ == other.field_float_
+   && field_sint64_ == other.field_sint64_
+   && field_sint32_ == other.field_sint32_
+   && field_string_ == other.field_string_
+   && 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 */:
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TestConfig_DummyFields::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TestConfig_DummyFields::Serialize(::protozero::Message* msg) const {
+  // Field 1: field_uint32
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, field_uint32_);
+  }
+
+  // Field 2: field_int32
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, field_int32_);
+  }
+
+  // Field 3: field_uint64
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, field_uint64_);
+  }
+
+  // Field 4: field_int64
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, field_int64_);
+  }
+
+  // Field 5: field_fixed64
+  if (_has_field_[5]) {
+    msg->AppendFixed(5, field_fixed64_);
+  }
+
+  // Field 6: field_sfixed64
+  if (_has_field_[6]) {
+    msg->AppendFixed(6, field_sfixed64_);
+  }
+
+  // Field 7: field_fixed32
+  if (_has_field_[7]) {
+    msg->AppendFixed(7, field_fixed32_);
+  }
+
+  // Field 8: field_sfixed32
+  if (_has_field_[8]) {
+    msg->AppendFixed(8, field_sfixed32_);
+  }
+
+  // Field 9: field_double
+  if (_has_field_[9]) {
+    msg->AppendFixed(9, field_double_);
+  }
+
+  // Field 10: field_float
+  if (_has_field_[10]) {
+    msg->AppendFixed(10, field_float_);
+  }
+
+  // Field 11: field_sint64
+  if (_has_field_[11]) {
+    msg->AppendSignedVarInt(11, field_sint64_);
+  }
+
+  // Field 12: field_sint32
+  if (_has_field_[12]) {
+    msg->AppendSignedVarInt(12, field_sint32_);
+  }
+
+  // Field 13: field_string
+  if (_has_field_[13]) {
+    msg->AppendString(13, field_string_);
+  }
+
+  // Field 14: field_bytes
+  if (_has_field_[14]) {
+    msg->AppendString(14, field_bytes_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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/message.h"
+// gen_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/common/builtin_clock.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.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/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/chrome/chrome_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_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"
+
+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 unknown_fields_ == other.unknown_fields_
+   && buffers_ == other.buffers_
+   && data_sources_ == other.data_sources_
+   && builtin_data_sources_ == other.builtin_data_sources_
+   && duration_ms_ == other.duration_ms_
+   && enable_extra_guardrails_ == other.enable_extra_guardrails_
+   && lockdown_mode_ == other.lockdown_mode_
+   && producers_ == other.producers_
+   && statsd_metadata_ == other.statsd_metadata_
+   && write_into_file_ == other.write_into_file_
+   && output_path_ == other.output_path_
+   && file_write_period_ms_ == other.file_write_period_ms_
+   && max_file_size_bytes_ == other.max_file_size_bytes_
+   && guardrail_overrides_ == other.guardrail_overrides_
+   && deferred_start_ == other.deferred_start_
+   && flush_period_ms_ == other.flush_period_ms_
+   && flush_timeout_ms_ == other.flush_timeout_ms_
+   && data_source_stop_timeout_ms_ == other.data_source_stop_timeout_ms_
+   && notify_traceur_ == other.notify_traceur_
+   && bugreport_score_ == other.bugreport_score_
+   && trigger_config_ == other.trigger_config_
+   && activate_triggers_ == other.activate_triggers_
+   && incremental_state_config_ == other.incremental_state_config_
+   && allow_user_build_tracing_ == other.allow_user_build_tracing_
+   && unique_session_name_ == other.unique_session_name_
+   && compression_type_ == other.compression_type_
+   && incident_report_config_ == other.incident_report_config_
+   && statsd_logging_ == other.statsd_logging_
+   && trace_uuid_msb_ == other.trace_uuid_msb_
+   && trace_uuid_lsb_ == other.trace_uuid_lsb_
+   && trace_filter_ == other.trace_filter_;
+}
+
+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 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 */:
+        field.get(&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();
+        field.get(&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 */:
+        field.get(&unique_session_name_);
+        break;
+      case 24 /* compression_type */:
+        field.get(&compression_type_);
+        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 32 /* trace_filter */:
+        (*trace_filter_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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]) {
+    msg->AppendVarInt(3, duration_ms_);
+  }
+
+  // Field 4: enable_extra_guardrails
+  if (_has_field_[4]) {
+    msg->AppendTinyVarInt(4, enable_extra_guardrails_);
+  }
+
+  // Field 5: lockdown_mode
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, lockdown_mode_);
+  }
+
+  // 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]) {
+    msg->AppendTinyVarInt(8, write_into_file_);
+  }
+
+  // Field 29: output_path
+  if (_has_field_[29]) {
+    msg->AppendString(29, output_path_);
+  }
+
+  // Field 9: file_write_period_ms
+  if (_has_field_[9]) {
+    msg->AppendVarInt(9, file_write_period_ms_);
+  }
+
+  // Field 10: max_file_size_bytes
+  if (_has_field_[10]) {
+    msg->AppendVarInt(10, max_file_size_bytes_);
+  }
+
+  // Field 11: guardrail_overrides
+  if (_has_field_[11]) {
+    (*guardrail_overrides_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
+  }
+
+  // Field 12: deferred_start
+  if (_has_field_[12]) {
+    msg->AppendTinyVarInt(12, deferred_start_);
+  }
+
+  // Field 13: flush_period_ms
+  if (_has_field_[13]) {
+    msg->AppendVarInt(13, flush_period_ms_);
+  }
+
+  // Field 14: flush_timeout_ms
+  if (_has_field_[14]) {
+    msg->AppendVarInt(14, flush_timeout_ms_);
+  }
+
+  // Field 23: data_source_stop_timeout_ms
+  if (_has_field_[23]) {
+    msg->AppendVarInt(23, data_source_stop_timeout_ms_);
+  }
+
+  // Field 16: notify_traceur
+  if (_has_field_[16]) {
+    msg->AppendTinyVarInt(16, notify_traceur_);
+  }
+
+  // Field 30: bugreport_score
+  if (_has_field_[30]) {
+    msg->AppendVarInt(30, bugreport_score_);
+  }
+
+  // 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_) {
+    msg->AppendString(18, it);
+  }
+
+  // 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]) {
+    msg->AppendTinyVarInt(19, allow_user_build_tracing_);
+  }
+
+  // Field 22: unique_session_name
+  if (_has_field_[22]) {
+    msg->AppendString(22, unique_session_name_);
+  }
+
+  // Field 24: compression_type
+  if (_has_field_[24]) {
+    msg->AppendVarInt(24, compression_type_);
+  }
+
+  // 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]) {
+    msg->AppendVarInt(31, statsd_logging_);
+  }
+
+  // Field 27: trace_uuid_msb
+  if (_has_field_[27]) {
+    msg->AppendVarInt(27, trace_uuid_msb_);
+  }
+
+  // Field 28: trace_uuid_lsb
+  if (_has_field_[28]) {
+    msg->AppendVarInt(28, trace_uuid_lsb_);
+  }
+
+  // Field 32: trace_filter
+  if (_has_field_[32]) {
+    (*trace_filter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(32));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && bytecode_ == other.bytecode_;
+}
+
+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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_TraceFilter::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_TraceFilter::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_TraceFilter::Serialize(::protozero::Message* msg) const {
+  // Field 1: bytecode
+  if (_has_field_[1]) {
+    msg->AppendString(1, bytecode_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && destination_package_ == other.destination_package_
+   && destination_class_ == other.destination_class_
+   && privacy_level_ == other.privacy_level_
+   && skip_incidentd_ == other.skip_incidentd_
+   && 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 */:
+        field.get(&destination_package_);
+        break;
+      case 2 /* destination_class */:
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_IncidentReportConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_IncidentReportConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: destination_package
+  if (_has_field_[1]) {
+    msg->AppendString(1, destination_package_);
+  }
+
+  // Field 2: destination_class
+  if (_has_field_[2]) {
+    msg->AppendString(2, destination_class_);
+  }
+
+  // Field 3: privacy_level
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, privacy_level_);
+  }
+
+  // Field 5: skip_incidentd
+  if (_has_field_[5]) {
+    msg->AppendTinyVarInt(5, skip_incidentd_);
+  }
+
+  // Field 4: skip_dropbox
+  if (_has_field_[4]) {
+    msg->AppendTinyVarInt(4, skip_dropbox_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_IncrementalStateConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_IncrementalStateConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: clear_period_ms
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, clear_period_ms_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && trigger_mode_ == other.trigger_mode_
+   && triggers_ == other.triggers_
+   && 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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_TriggerConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_TriggerConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: trigger_mode
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, trigger_mode_);
+  }
+
+  // Field 2: triggers
+  for (auto& it : triggers_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 3: trigger_timeout_ms
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, trigger_timeout_ms_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && name_ == other.name_
+   && producer_name_regex_ == other.producer_name_regex_
+   && stop_delay_ms_ == other.stop_delay_ms_
+   && max_per_24_h_ == other.max_per_24_h_
+   && 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 */:
+        field.get(&name_);
+        break;
+      case 2 /* producer_name_regex */:
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_TriggerConfig_Trigger::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_TriggerConfig_Trigger::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    msg->AppendString(1, name_);
+  }
+
+  // Field 2: producer_name_regex
+  if (_has_field_[2]) {
+    msg->AppendString(2, producer_name_regex_);
+  }
+
+  // Field 3: stop_delay_ms
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, stop_delay_ms_);
+  }
+
+  // Field 4: max_per_24_h
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, max_per_24_h_);
+  }
+
+  // Field 5: skip_probability
+  if (_has_field_[5]) {
+    msg->AppendFixed(5, skip_probability_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && max_upload_per_day_bytes_ == other.max_upload_per_day_bytes_;
+}
+
+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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_GuardrailOverrides::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_GuardrailOverrides::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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]) {
+    msg->AppendVarInt(1, max_upload_per_day_bytes_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && triggering_alert_id_ == other.triggering_alert_id_
+   && triggering_config_uid_ == other.triggering_config_uid_
+   && triggering_config_id_ == other.triggering_config_id_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_StatsdMetadata::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_StatsdMetadata::Serialize(::protozero::Message* msg) const {
+  // Field 1: triggering_alert_id
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, triggering_alert_id_);
+  }
+
+  // Field 2: triggering_config_uid
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, triggering_config_uid_);
+  }
+
+  // Field 3: triggering_config_id
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, triggering_config_id_);
+  }
+
+  // Field 4: triggering_subscription_id
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, triggering_subscription_id_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && producer_name_ == other.producer_name_
+   && shm_size_kb_ == other.shm_size_kb_
+   && 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 */:
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_ProducerConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_ProducerConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: producer_name
+  if (_has_field_[1]) {
+    msg->AppendString(1, producer_name_);
+  }
+
+  // Field 2: shm_size_kb
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, shm_size_kb_);
+  }
+
+  // Field 3: page_size_kb
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, page_size_kb_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && disable_clock_snapshotting_ == other.disable_clock_snapshotting_
+   && disable_trace_config_ == other.disable_trace_config_
+   && disable_system_info_ == other.disable_system_info_
+   && disable_service_events_ == other.disable_service_events_
+   && primary_trace_clock_ == other.primary_trace_clock_
+   && snapshot_interval_ms_ == other.snapshot_interval_ms_
+   && prefer_suspend_clock_for_snapshot_ == other.prefer_suspend_clock_for_snapshot_;
+}
+
+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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_BuiltinDataSource::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_BuiltinDataSource::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_BuiltinDataSource::Serialize(::protozero::Message* msg) const {
+  // Field 1: disable_clock_snapshotting
+  if (_has_field_[1]) {
+    msg->AppendTinyVarInt(1, disable_clock_snapshotting_);
+  }
+
+  // Field 2: disable_trace_config
+  if (_has_field_[2]) {
+    msg->AppendTinyVarInt(2, disable_trace_config_);
+  }
+
+  // Field 3: disable_system_info
+  if (_has_field_[3]) {
+    msg->AppendTinyVarInt(3, disable_system_info_);
+  }
+
+  // Field 4: disable_service_events
+  if (_has_field_[4]) {
+    msg->AppendTinyVarInt(4, disable_service_events_);
+  }
+
+  // Field 5: primary_trace_clock
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, primary_trace_clock_);
+  }
+
+  // Field 6: snapshot_interval_ms
+  if (_has_field_[6]) {
+    msg->AppendVarInt(6, snapshot_interval_ms_);
+  }
+
+  // Field 7: prefer_suspend_clock_for_snapshot
+  if (_has_field_[7]) {
+    msg->AppendTinyVarInt(7, prefer_suspend_clock_for_snapshot_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && config_ == other.config_
+   && producer_name_filter_ == other.producer_name_filter_
+   && 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();
+        field.get(&producer_name_filter_.back());
+        break;
+      case 3 /* producer_name_regex_filter */:
+        producer_name_regex_filter_.emplace_back();
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_DataSource::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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_) {
+    msg->AppendString(2, it);
+  }
+
+  // Field 3: producer_name_regex_filter
+  for (auto& it : producer_name_regex_filter_) {
+    msg->AppendString(3, it);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && size_kb_ == other.size_kb_
+   && fill_policy_ == other.fill_policy_;
+}
+
+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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_BufferConfig::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_BufferConfig::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_BufferConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: size_kb
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, size_kb_);
+  }
+
+  // Field 4: fill_policy
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, fill_policy_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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/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/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_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/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_application_state_info.gen.cc
+// 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeApplicationStateInfo::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeApplicationStateInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: application_state
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, application_state_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 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 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 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 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 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 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 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 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 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/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;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT 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_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_CPP_H_
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && begin_main_frame_queue_critical_estimate_delta_us_ == other.begin_main_frame_queue_critical_estimate_delta_us_
+   && begin_main_frame_queue_not_critical_estimate_delta_us_ == other.begin_main_frame_queue_not_critical_estimate_delta_us_
+   && begin_main_frame_start_to_ready_to_commit_estimate_delta_us_ == other.begin_main_frame_start_to_ready_to_commit_estimate_delta_us_
+   && commit_to_ready_to_activate_estimate_delta_us_ == other.commit_to_ready_to_activate_estimate_delta_us_
+   && prepare_tiles_estimate_delta_us_ == other.prepare_tiles_estimate_delta_us_
+   && activate_estimate_delta_us_ == other.activate_estimate_delta_us_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CompositorTimingHistory::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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]) {
+    msg->AppendVarInt(1, begin_main_frame_queue_critical_estimate_delta_us_);
+  }
+
+  // Field 2: begin_main_frame_queue_not_critical_estimate_delta_us
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, begin_main_frame_queue_not_critical_estimate_delta_us_);
+  }
+
+  // Field 3: begin_main_frame_start_to_ready_to_commit_estimate_delta_us
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, begin_main_frame_start_to_ready_to_commit_estimate_delta_us_);
+  }
+
+  // Field 4: commit_to_ready_to_activate_estimate_delta_us
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, commit_to_ready_to_activate_estimate_delta_us_);
+  }
+
+  // Field 5: prepare_tiles_estimate_delta_us
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, prepare_tiles_estimate_delta_us_);
+  }
+
+  // Field 6: activate_estimate_delta_us
+  if (_has_field_[6]) {
+    msg->AppendVarInt(6, activate_estimate_delta_us_);
+  }
+
+  // Field 7: draw_estimate_delta_us
+  if (_has_field_[7]) {
+    msg->AppendVarInt(7, draw_estimate_delta_us_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && source_id_ == other.source_id_
+   && paused_ == other.paused_
+   && num_observers_ == other.num_observers_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> BeginFrameSourceState::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void BeginFrameSourceState::Serialize(::protozero::Message* msg) const {
+  // Field 1: source_id
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, source_id_);
+  }
+
+  // Field 2: paused
+  if (_has_field_[2]) {
+    msg->AppendTinyVarInt(2, paused_);
+  }
+
+  // Field 3: num_observers
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, num_observers_);
+  }
+
+  // Field 4: last_begin_frame_args
+  if (_has_field_[4]) {
+    (*last_begin_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && type_ == other.type_
+   && source_id_ == other.source_id_
+   && sequence_number_ == other.sequence_number_
+   && frame_time_us_ == other.frame_time_us_
+   && deadline_us_ == other.deadline_us_
+   && interval_delta_us_ == other.interval_delta_us_
+   && on_critical_path_ == other.on_critical_path_
+   && animate_only_ == other.animate_only_
+   && source_location_iid_ == other.source_location_iid_
+   && source_location_ == other.source_location_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> BeginFrameArgs::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void BeginFrameArgs::Serialize(::protozero::Message* msg) const {
+  // Field 1: type
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, type_);
+  }
+
+  // Field 2: source_id
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, source_id_);
+  }
+
+  // Field 3: sequence_number
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, sequence_number_);
+  }
+
+  // Field 4: frame_time_us
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, frame_time_us_);
+  }
+
+  // Field 5: deadline_us
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, deadline_us_);
+  }
+
+  // Field 6: interval_delta_us
+  if (_has_field_[6]) {
+    msg->AppendVarInt(6, interval_delta_us_);
+  }
+
+  // Field 7: on_critical_path
+  if (_has_field_[7]) {
+    msg->AppendTinyVarInt(7, on_critical_path_);
+  }
+
+  // Field 8: animate_only
+  if (_has_field_[8]) {
+    msg->AppendTinyVarInt(8, animate_only_);
+  }
+
+  // Field 9: source_location_iid
+  if (_has_field_[9]) {
+    msg->AppendVarInt(9, source_location_iid_);
+  }
+
+  // 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]) {
+    msg->AppendVarInt(12, frames_throttled_since_last_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && dropped_begin_frame_args_ == other.dropped_begin_frame_args_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> BeginFrameObserverState::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void BeginFrameObserverState::Serialize(::protozero::Message* msg) const {
+  // Field 1: dropped_begin_frame_args
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, dropped_begin_frame_args_);
+  }
+
+  // Field 2: last_begin_frame_args
+  if (_has_field_[2]) {
+    (*last_begin_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && updated_at_us_ == other.updated_at_us_
+   && finished_at_us_ == other.finished_at_us_
+   && state_ == other.state_
+   && current_args_ == other.current_args_
+   && last_args_ == other.last_args_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> BeginImplFrameArgs::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void BeginImplFrameArgs::Serialize(::protozero::Message* msg) const {
+  // Field 1: updated_at_us
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, updated_at_us_);
+  }
+
+  // Field 2: finished_at_us
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, finished_at_us_);
+  }
+
+  // Field 3: state
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, state_);
+  }
+
+  // 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));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && interval_delta_ == other.interval_delta_
+   && now_to_deadline_delta_ == other.now_to_deadline_delta_
+   && frame_time_to_now_delta_ == other.frame_time_to_now_delta_
+   && frame_time_to_deadline_delta_ == other.frame_time_to_deadline_delta_
+   && now_ == other.now_
+   && frame_time_ == other.frame_time_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> BeginImplFrameArgs_TimestampsInUs::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void BeginImplFrameArgs_TimestampsInUs::Serialize(::protozero::Message* msg) const {
+  // Field 1: interval_delta
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, interval_delta_);
+  }
+
+  // Field 2: now_to_deadline_delta
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, now_to_deadline_delta_);
+  }
+
+  // Field 3: frame_time_to_now_delta
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, frame_time_to_now_delta_);
+  }
+
+  // Field 4: frame_time_to_deadline_delta
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, frame_time_to_deadline_delta_);
+  }
+
+  // Field 5: now
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, now_);
+  }
+
+  // Field 6: frame_time
+  if (_has_field_[6]) {
+    msg->AppendVarInt(6, frame_time_);
+  }
+
+  // Field 7: deadline
+  if (_has_field_[7]) {
+    msg->AppendVarInt(7, deadline_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && major_state_ == other.major_state_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeCompositorStateMachine::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && commit_count_ == other.commit_count_
+   && current_frame_number_ == other.current_frame_number_
+   && last_frame_number_submit_performed_ == other.last_frame_number_submit_performed_
+   && last_frame_number_draw_performed_ == other.last_frame_number_draw_performed_
+   && last_frame_number_begin_main_frame_sent_ == other.last_frame_number_begin_main_frame_sent_
+   && did_draw_ == other.did_draw_
+   && did_send_begin_main_frame_for_current_frame_ == other.did_send_begin_main_frame_for_current_frame_
+   && did_notify_begin_main_frame_not_expected_until_ == other.did_notify_begin_main_frame_not_expected_until_
+   && did_notify_begin_main_frame_not_expected_soon_ == other.did_notify_begin_main_frame_not_expected_soon_
+   && wants_begin_main_frame_not_expected_ == other.wants_begin_main_frame_not_expected_
+   && did_commit_during_frame_ == other.did_commit_during_frame_
+   && did_invalidate_layer_tree_frame_sink_ == other.did_invalidate_layer_tree_frame_sink_
+   && did_perform_impl_side_invalidaion_ == other.did_perform_impl_side_invalidaion_
+   && did_prepare_tiles_ == other.did_prepare_tiles_
+   && consecutive_checkerboard_animations_ == other.consecutive_checkerboard_animations_
+   && pending_submit_frames_ == other.pending_submit_frames_
+   && submit_frames_with_current_layer_tree_frame_sink_ == other.submit_frames_with_current_layer_tree_frame_sink_
+   && needs_redraw_ == other.needs_redraw_
+   && needs_prepare_tiles_ == other.needs_prepare_tiles_
+   && needs_begin_main_frame_ == other.needs_begin_main_frame_
+   && needs_one_begin_impl_frame_ == other.needs_one_begin_impl_frame_
+   && visible_ == other.visible_
+   && begin_frame_source_paused_ == other.begin_frame_source_paused_
+   && can_draw_ == other.can_draw_
+   && resourceless_draw_ == other.resourceless_draw_
+   && has_pending_tree_ == other.has_pending_tree_
+   && pending_tree_is_ready_for_activation_ == other.pending_tree_is_ready_for_activation_
+   && active_tree_needs_first_draw_ == other.active_tree_needs_first_draw_
+   && active_tree_is_ready_to_draw_ == other.active_tree_is_ready_to_draw_
+   && did_create_and_initialize_first_layer_tree_frame_sink_ == other.did_create_and_initialize_first_layer_tree_frame_sink_
+   && tree_priority_ == other.tree_priority_
+   && scroll_handler_state_ == other.scroll_handler_state_
+   && critical_begin_main_frame_to_activate_is_fast_ == other.critical_begin_main_frame_to_activate_is_fast_
+   && main_thread_missed_last_deadline_ == other.main_thread_missed_last_deadline_
+   && video_needs_begin_frames_ == other.video_needs_begin_frames_
+   && defer_begin_main_frame_ == other.defer_begin_main_frame_
+   && last_commit_had_no_updates_ == other.last_commit_had_no_updates_
+   && did_draw_in_last_frame_ == other.did_draw_in_last_frame_
+   && did_submit_in_last_frame_ == other.did_submit_in_last_frame_
+   && needs_impl_side_invalidation_ == other.needs_impl_side_invalidation_
+   && current_pending_tree_is_impl_side_ == other.current_pending_tree_is_impl_side_
+   && previous_pending_tree_was_impl_side_ == other.previous_pending_tree_was_impl_side_
+   && processing_animation_worklets_for_active_tree_ == other.processing_animation_worklets_for_active_tree_
+   && processing_animation_worklets_for_pending_tree_ == other.processing_animation_worklets_for_pending_tree_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeCompositorStateMachine_MinorState::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeCompositorStateMachine_MinorState::Serialize(::protozero::Message* msg) const {
+  // Field 1: commit_count
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, commit_count_);
+  }
+
+  // Field 2: current_frame_number
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, current_frame_number_);
+  }
+
+  // Field 3: last_frame_number_submit_performed
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, last_frame_number_submit_performed_);
+  }
+
+  // Field 4: last_frame_number_draw_performed
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, last_frame_number_draw_performed_);
+  }
+
+  // Field 5: last_frame_number_begin_main_frame_sent
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, last_frame_number_begin_main_frame_sent_);
+  }
+
+  // Field 6: did_draw
+  if (_has_field_[6]) {
+    msg->AppendTinyVarInt(6, did_draw_);
+  }
+
+  // Field 7: did_send_begin_main_frame_for_current_frame
+  if (_has_field_[7]) {
+    msg->AppendTinyVarInt(7, did_send_begin_main_frame_for_current_frame_);
+  }
+
+  // Field 8: did_notify_begin_main_frame_not_expected_until
+  if (_has_field_[8]) {
+    msg->AppendTinyVarInt(8, did_notify_begin_main_frame_not_expected_until_);
+  }
+
+  // Field 9: did_notify_begin_main_frame_not_expected_soon
+  if (_has_field_[9]) {
+    msg->AppendTinyVarInt(9, did_notify_begin_main_frame_not_expected_soon_);
+  }
+
+  // Field 10: wants_begin_main_frame_not_expected
+  if (_has_field_[10]) {
+    msg->AppendTinyVarInt(10, wants_begin_main_frame_not_expected_);
+  }
+
+  // Field 11: did_commit_during_frame
+  if (_has_field_[11]) {
+    msg->AppendTinyVarInt(11, did_commit_during_frame_);
+  }
+
+  // Field 12: did_invalidate_layer_tree_frame_sink
+  if (_has_field_[12]) {
+    msg->AppendTinyVarInt(12, did_invalidate_layer_tree_frame_sink_);
+  }
+
+  // Field 13: did_perform_impl_side_invalidaion
+  if (_has_field_[13]) {
+    msg->AppendTinyVarInt(13, did_perform_impl_side_invalidaion_);
+  }
+
+  // Field 14: did_prepare_tiles
+  if (_has_field_[14]) {
+    msg->AppendTinyVarInt(14, did_prepare_tiles_);
+  }
+
+  // Field 15: consecutive_checkerboard_animations
+  if (_has_field_[15]) {
+    msg->AppendVarInt(15, consecutive_checkerboard_animations_);
+  }
+
+  // Field 16: pending_submit_frames
+  if (_has_field_[16]) {
+    msg->AppendVarInt(16, pending_submit_frames_);
+  }
+
+  // Field 17: submit_frames_with_current_layer_tree_frame_sink
+  if (_has_field_[17]) {
+    msg->AppendVarInt(17, submit_frames_with_current_layer_tree_frame_sink_);
+  }
+
+  // Field 18: needs_redraw
+  if (_has_field_[18]) {
+    msg->AppendTinyVarInt(18, needs_redraw_);
+  }
+
+  // Field 19: needs_prepare_tiles
+  if (_has_field_[19]) {
+    msg->AppendTinyVarInt(19, needs_prepare_tiles_);
+  }
+
+  // Field 20: needs_begin_main_frame
+  if (_has_field_[20]) {
+    msg->AppendTinyVarInt(20, needs_begin_main_frame_);
+  }
+
+  // Field 21: needs_one_begin_impl_frame
+  if (_has_field_[21]) {
+    msg->AppendTinyVarInt(21, needs_one_begin_impl_frame_);
+  }
+
+  // Field 22: visible
+  if (_has_field_[22]) {
+    msg->AppendTinyVarInt(22, visible_);
+  }
+
+  // Field 23: begin_frame_source_paused
+  if (_has_field_[23]) {
+    msg->AppendTinyVarInt(23, begin_frame_source_paused_);
+  }
+
+  // Field 24: can_draw
+  if (_has_field_[24]) {
+    msg->AppendTinyVarInt(24, can_draw_);
+  }
+
+  // Field 25: resourceless_draw
+  if (_has_field_[25]) {
+    msg->AppendTinyVarInt(25, resourceless_draw_);
+  }
+
+  // Field 26: has_pending_tree
+  if (_has_field_[26]) {
+    msg->AppendTinyVarInt(26, has_pending_tree_);
+  }
+
+  // Field 27: pending_tree_is_ready_for_activation
+  if (_has_field_[27]) {
+    msg->AppendTinyVarInt(27, pending_tree_is_ready_for_activation_);
+  }
+
+  // Field 28: active_tree_needs_first_draw
+  if (_has_field_[28]) {
+    msg->AppendTinyVarInt(28, active_tree_needs_first_draw_);
+  }
+
+  // Field 29: active_tree_is_ready_to_draw
+  if (_has_field_[29]) {
+    msg->AppendTinyVarInt(29, active_tree_is_ready_to_draw_);
+  }
+
+  // Field 30: did_create_and_initialize_first_layer_tree_frame_sink
+  if (_has_field_[30]) {
+    msg->AppendTinyVarInt(30, did_create_and_initialize_first_layer_tree_frame_sink_);
+  }
+
+  // Field 31: tree_priority
+  if (_has_field_[31]) {
+    msg->AppendVarInt(31, tree_priority_);
+  }
+
+  // Field 32: scroll_handler_state
+  if (_has_field_[32]) {
+    msg->AppendVarInt(32, scroll_handler_state_);
+  }
+
+  // Field 33: critical_begin_main_frame_to_activate_is_fast
+  if (_has_field_[33]) {
+    msg->AppendTinyVarInt(33, critical_begin_main_frame_to_activate_is_fast_);
+  }
+
+  // Field 34: main_thread_missed_last_deadline
+  if (_has_field_[34]) {
+    msg->AppendTinyVarInt(34, main_thread_missed_last_deadline_);
+  }
+
+  // Field 36: video_needs_begin_frames
+  if (_has_field_[36]) {
+    msg->AppendTinyVarInt(36, video_needs_begin_frames_);
+  }
+
+  // Field 37: defer_begin_main_frame
+  if (_has_field_[37]) {
+    msg->AppendTinyVarInt(37, defer_begin_main_frame_);
+  }
+
+  // Field 38: last_commit_had_no_updates
+  if (_has_field_[38]) {
+    msg->AppendTinyVarInt(38, last_commit_had_no_updates_);
+  }
+
+  // Field 39: did_draw_in_last_frame
+  if (_has_field_[39]) {
+    msg->AppendTinyVarInt(39, did_draw_in_last_frame_);
+  }
+
+  // Field 40: did_submit_in_last_frame
+  if (_has_field_[40]) {
+    msg->AppendTinyVarInt(40, did_submit_in_last_frame_);
+  }
+
+  // Field 41: needs_impl_side_invalidation
+  if (_has_field_[41]) {
+    msg->AppendTinyVarInt(41, needs_impl_side_invalidation_);
+  }
+
+  // Field 42: current_pending_tree_is_impl_side
+  if (_has_field_[42]) {
+    msg->AppendTinyVarInt(42, current_pending_tree_is_impl_side_);
+  }
+
+  // Field 43: previous_pending_tree_was_impl_side
+  if (_has_field_[43]) {
+    msg->AppendTinyVarInt(43, previous_pending_tree_was_impl_side_);
+  }
+
+  // Field 44: processing_animation_worklets_for_active_tree
+  if (_has_field_[44]) {
+    msg->AppendTinyVarInt(44, processing_animation_worklets_for_active_tree_);
+  }
+
+  // Field 45: processing_animation_worklets_for_pending_tree
+  if (_has_field_[45]) {
+    msg->AppendTinyVarInt(45, processing_animation_worklets_for_pending_tree_);
+  }
+
+  // Field 46: processing_paint_worklets_for_pending_tree
+  if (_has_field_[46]) {
+    msg->AppendTinyVarInt(46, processing_paint_worklets_for_pending_tree_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && next_action_ == other.next_action_
+   && begin_impl_frame_state_ == other.begin_impl_frame_state_
+   && begin_main_frame_state_ == other.begin_main_frame_state_
+   && layer_tree_frame_sink_state_ == other.layer_tree_frame_sink_state_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeCompositorStateMachine_MajorState::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeCompositorStateMachine_MajorState::Serialize(::protozero::Message* msg) const {
+  // Field 1: next_action
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, next_action_);
+  }
+
+  // Field 2: begin_impl_frame_state
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, begin_impl_frame_state_);
+  }
+
+  // Field 3: begin_main_frame_state
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, begin_main_frame_state_);
+  }
+
+  // Field 4: layer_tree_frame_sink_state
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, layer_tree_frame_sink_state_);
+  }
+
+  // Field 5: forced_redraw_state
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, forced_redraw_state_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && state_machine_ == other.state_machine_
+   && observing_begin_frame_source_ == other.observing_begin_frame_source_
+   && begin_impl_frame_deadline_task_ == other.begin_impl_frame_deadline_task_
+   && pending_begin_frame_task_ == other.pending_begin_frame_task_
+   && skipped_last_frame_missed_exceeded_deadline_ == other.skipped_last_frame_missed_exceeded_deadline_
+   && inside_action_ == other.inside_action_
+   && deadline_mode_ == other.deadline_mode_
+   && deadline_us_ == other.deadline_us_
+   && deadline_scheduled_at_us_ == other.deadline_scheduled_at_us_
+   && now_us_ == other.now_us_
+   && now_to_deadline_delta_us_ == other.now_to_deadline_delta_us_
+   && now_to_deadline_scheduled_at_delta_us_ == other.now_to_deadline_scheduled_at_delta_us_
+   && begin_impl_frame_args_ == other.begin_impl_frame_args_
+   && begin_frame_observer_state_ == other.begin_frame_observer_state_
+   && begin_frame_source_state_ == other.begin_frame_source_state_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeCompositorSchedulerState::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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]) {
+    msg->AppendTinyVarInt(2, observing_begin_frame_source_);
+  }
+
+  // Field 3: begin_impl_frame_deadline_task
+  if (_has_field_[3]) {
+    msg->AppendTinyVarInt(3, begin_impl_frame_deadline_task_);
+  }
+
+  // Field 4: pending_begin_frame_task
+  if (_has_field_[4]) {
+    msg->AppendTinyVarInt(4, pending_begin_frame_task_);
+  }
+
+  // Field 5: skipped_last_frame_missed_exceeded_deadline
+  if (_has_field_[5]) {
+    msg->AppendTinyVarInt(5, skipped_last_frame_missed_exceeded_deadline_);
+  }
+
+  // Field 7: inside_action
+  if (_has_field_[7]) {
+    msg->AppendVarInt(7, inside_action_);
+  }
+
+  // Field 8: deadline_mode
+  if (_has_field_[8]) {
+    msg->AppendVarInt(8, deadline_mode_);
+  }
+
+  // Field 9: deadline_us
+  if (_has_field_[9]) {
+    msg->AppendVarInt(9, deadline_us_);
+  }
+
+  // Field 10: deadline_scheduled_at_us
+  if (_has_field_[10]) {
+    msg->AppendVarInt(10, deadline_scheduled_at_us_);
+  }
+
+  // Field 11: now_us
+  if (_has_field_[11]) {
+    msg->AppendVarInt(11, now_us_);
+  }
+
+  // Field 12: now_to_deadline_delta_us
+  if (_has_field_[12]) {
+    msg->AppendVarInt(12, now_to_deadline_delta_us_);
+  }
+
+  // Field 13: now_to_deadline_scheduled_at_delta_us
+  if (_has_field_[13]) {
+    msg->AppendVarInt(13, now_to_deadline_scheduled_at_delta_us_);
+  }
+
+  // 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));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeContentSettingsEventInfo::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeContentSettingsEventInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: number_of_exceptions
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, number_of_exceptions_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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;
+}  // 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,
+};
+
+class PERFETTO_EXPORT 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;
+  enum FieldNumbers {
+    kStateFieldNumber = 1,
+    kReasonFieldNumber = 2,
+    kFrameSourceFieldNumber = 3,
+    kFrameSequenceFieldNumber = 4,
+    kAffectsSmoothnessFieldNumber = 5,
+    kScrollStateFieldNumber = 6,
+    kHasMainAnimationFieldNumber = 7,
+    kHasCompositorAnimationFieldNumber = 8,
+    kHasSmoothInputMainFieldNumber = 9,
+    kHasMissingContentFieldNumber = 10,
+    kLayerTreeHostIdFieldNumber = 11,
+  };
+
+  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); }
+
+ 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_{};
+
+  // 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_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_CPP_H_
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && state_ == other.state_
+   && reason_ == other.reason_
+   && frame_source_ == other.frame_source_
+   && frame_sequence_ == other.frame_sequence_
+   && affects_smoothness_ == other.affects_smoothness_
+   && scroll_state_ == other.scroll_state_
+   && has_main_animation_ == other.has_main_animation_
+   && has_compositor_animation_ == other.has_compositor_animation_
+   && has_smooth_input_main_ == other.has_smooth_input_main_
+   && has_missing_content_ == other.has_missing_content_
+   && layer_tree_host_id_ == other.layer_tree_host_id_;
+}
+
+bool ChromeFrameReporter::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 */:
+        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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeFrameReporter::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeFrameReporter::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeFrameReporter::Serialize(::protozero::Message* msg) const {
+  // Field 1: state
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, state_);
+  }
+
+  // Field 2: reason
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, reason_);
+  }
+
+  // Field 3: frame_source
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, frame_source_);
+  }
+
+  // Field 4: frame_sequence
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, frame_sequence_);
+  }
+
+  // Field 5: affects_smoothness
+  if (_has_field_[5]) {
+    msg->AppendTinyVarInt(5, affects_smoothness_);
+  }
+
+  // Field 6: scroll_state
+  if (_has_field_[6]) {
+    msg->AppendVarInt(6, scroll_state_);
+  }
+
+  // Field 7: has_main_animation
+  if (_has_field_[7]) {
+    msg->AppendTinyVarInt(7, has_main_animation_);
+  }
+
+  // Field 8: has_compositor_animation
+  if (_has_field_[8]) {
+    msg->AppendTinyVarInt(8, has_compositor_animation_);
+  }
+
+  // Field 9: has_smooth_input_main
+  if (_has_field_[9]) {
+    msg->AppendTinyVarInt(9, has_smooth_input_main_);
+  }
+
+  // Field 10: has_missing_content
+  if (_has_field_[10]) {
+    msg->AppendTinyVarInt(10, has_missing_content_);
+  }
+
+  // Field 11: layer_tree_host_id
+  if (_has_field_[11]) {
+    msg->AppendVarInt(11, layer_tree_host_id_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && name_hash_ == other.name_hash_
+   && name_ == other.name_
+   && sample_ == other.sample_
+   && 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 */:
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeHistogramSample::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeHistogramSample::Serialize(::protozero::Message* msg) const {
+  // Field 1: name_hash
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, name_hash_);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    msg->AppendString(2, name_);
+  }
+
+  // Field 3: sample
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, sample_);
+  }
+
+  // Field 4: name_iid
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, name_iid_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && iid_ == other.iid_
+   && 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 */:
+        field.get(&name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string HistogramName::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> HistogramName::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void HistogramName::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, iid_);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    msg->AppendString(2, name_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && 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 */:
+        field.get(&name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeKeyedService::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeKeyedService::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeKeyedService::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    msg->AppendString(1, name_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && trace_id_ == other.trace_id_
+   && step_ == other.step_
+   && frame_tree_node_id_ == other.frame_tree_node_id_
+   && component_info_ == other.component_info_
+   && is_coalesced_ == other.is_coalesced_
+   && gesture_scroll_id_ == other.gesture_scroll_id_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeLatencyInfo::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeLatencyInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_id
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, trace_id_);
+  }
+
+  // Field 2: step
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, step_);
+  }
+
+  // Field 3: frame_tree_node_id
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, frame_tree_node_id_);
+  }
+
+  // Field 4: component_info
+  for (auto& it : component_info_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 5: is_coalesced
+  if (_has_field_[5]) {
+    msg->AppendTinyVarInt(5, is_coalesced_);
+  }
+
+  // Field 6: gesture_scroll_id
+  if (_has_field_[6]) {
+    msg->AppendVarInt(6, gesture_scroll_id_);
+  }
+
+  // Field 7: touch_id
+  if (_has_field_[7]) {
+    msg->AppendVarInt(7, touch_id_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && component_type_ == other.component_type_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeLatencyInfo_ComponentInfo::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeLatencyInfo_ComponentInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: component_type
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, component_type_);
+  }
+
+  // Field 2: time_us
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, time_us_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && message_class_ == other.message_class_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeLegacyIpc::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeLegacyIpc::Serialize(::protozero::Message* msg) const {
+  // Field 1: message_class
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, message_class_);
+  }
+
+  // Field 2: message_line
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, message_line_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && sent_messages_in_queue_ == other.sent_messages_in_queue_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeMessagePump::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeMessagePump::Serialize(::protozero::Message* msg) const {
+  // Field 1: sent_messages_in_queue
+  if (_has_field_[1]) {
+    msg->AppendTinyVarInt(1, sent_messages_in_queue_);
+  }
+
+  // Field 2: io_handler_location_iid
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, io_handler_location_iid_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 ChromeMojoEventInfo : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kWatcherNotifyInterfaceTagFieldNumber = 1,
+    kIpcHashFieldNumber = 2,
+    kMojoInterfaceTagFieldNumber = 3,
+  };
+
+  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); }
+
+ private:
+  std::string watcher_notify_interface_tag_{};
+  uint32_t ipc_hash_{};
+  std::string mojo_interface_tag_{};
+
+  // 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_MOJO_EVENT_INFO_PROTO_CPP_H_
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && watcher_notify_interface_tag_ == other.watcher_notify_interface_tag_
+   && ipc_hash_ == other.ipc_hash_
+   && mojo_interface_tag_ == other.mojo_interface_tag_;
+}
+
+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 */:
+        field.get(&watcher_notify_interface_tag_);
+        break;
+      case 2 /* ipc_hash */:
+        field.get(&ipc_hash_);
+        break;
+      case 3 /* mojo_interface_tag */:
+        field.get(&mojo_interface_tag_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeMojoEventInfo::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeMojoEventInfo::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeMojoEventInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: watcher_notify_interface_tag
+  if (_has_field_[1]) {
+    msg->AppendString(1, watcher_notify_interface_tag_);
+  }
+
+  // Field 2: ipc_hash
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, ipc_hash_);
+  }
+
+  // Field 3: mojo_interface_tag
+  if (_has_field_[3]) {
+    msg->AppendString(3, mojo_interface_tag_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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,
+};
+
+class PERFETTO_EXPORT 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 ProcessType_MIN = ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED;
+  static constexpr auto ProcessType_MAX = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHAPEDETECTION;
+  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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && process_type_ == other.process_type_
+   && process_priority_ == other.process_priority_
+   && legacy_sort_index_ == other.legacy_sort_index_
+   && host_app_package_name_ == other.host_app_package_name_
+   && 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 */:
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeProcessDescriptor::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeProcessDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: process_type
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, process_type_);
+  }
+
+  // Field 2: process_priority
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, process_priority_);
+  }
+
+  // Field 3: legacy_sort_index
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, legacy_sort_index_);
+  }
+
+  // Field 4: host_app_package_name
+  if (_has_field_[4]) {
+    msg->AppendString(4, host_app_package_name_);
+  }
+
+  // Field 5: crash_trace_id
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, crash_trace_id_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 ChromeRendererSchedulerState : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kRailModeFieldNumber = 1,
+  };
+
+  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); }
+
+ private:
+  ChromeRAILMode rail_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_TRACE_TRACK_EVENT_CHROME_RENDERER_SCHEDULER_STATE_PROTO_CPP_H_
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && rail_mode_ == other.rail_mode_;
+}
+
+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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeRendererSchedulerState::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeRendererSchedulerState::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeRendererSchedulerState::Serialize(::protozero::Message* msg) const {
+  // Field 1: rail_mode
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, rail_mode_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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_MEMORY_INFRA = 50,
+  ChromeThreadDescriptor_ThreadType_THREAD_SAMPLING_PROFILER = 51,
+};
+
+class PERFETTO_EXPORT 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_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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && thread_type_ == other.thread_type_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeThreadDescriptor::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeThreadDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: thread_type
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, thread_type_);
+  }
+
+  // Field 2: legacy_sort_index
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, legacy_sort_index_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && action_ == other.action_
+   && 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 */:
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeUserEvent::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeUserEvent::Serialize(::protozero::Message* msg) const {
+  // Field 1: action
+  if (_has_field_[1]) {
+    msg->AppendString(1, action_);
+  }
+
+  // Field 2: action_hash
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, action_hash_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && dpi_ == other.dpi_
+   && message_id_ == other.message_id_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeWindowHandleEventInfo::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeWindowHandleEventInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: dpi
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, dpi_);
+  }
+
+  // Field 2: message_id
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, message_id_);
+  }
+
+  // Field 3: hwnd_ptr
+  if (_has_field_[3]) {
+    msg->AppendFixed(3, hwnd_ptr_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && type_ == other.type_
+   && categories_ == other.categories_
+   && unit_ == other.unit_
+   && unit_name_ == other.unit_name_
+   && unit_multiplier_ == other.unit_multiplier_
+   && 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();
+        field.get(&categories_.back());
+        break;
+      case 3 /* unit */:
+        field.get(&unit_);
+        break;
+      case 6 /* unit_name */:
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CounterDescriptor::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CounterDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: type
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, type_);
+  }
+
+  // Field 2: categories
+  for (auto& it : categories_) {
+    msg->AppendString(2, it);
+  }
+
+  // Field 3: unit
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, unit_);
+  }
+
+  // Field 6: unit_name
+  if (_has_field_[6]) {
+    msg->AppendString(6, unit_name_);
+  }
+
+  // Field 4: unit_multiplier
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, unit_multiplier_);
+  }
+
+  // Field 5: is_incremental
+  if (_has_field_[5]) {
+    msg->AppendTinyVarInt(5, is_incremental_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 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 DebugAnnotation : public ::protozero::CppMessageObj {
+ public:
+  using NestedValue = DebugAnnotation_NestedValue;
+  enum FieldNumbers {
+    kNameIidFieldNumber = 1,
+    kNameFieldNumber = 10,
+    kBoolValueFieldNumber = 2,
+    kUintValueFieldNumber = 3,
+    kIntValueFieldNumber = 4,
+    kDoubleValueFieldNumber = 5,
+    kStringValueFieldNumber = 6,
+    kPointerValueFieldNumber = 7,
+    kNestedValueFieldNumber = 8,
+    kLegacyJsonValueFieldNumber = 9,
+    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_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_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); }
+
+  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_{};
+  std::string string_value_{};
+  uint64_t pointer_value_{};
+  ::protozero::CopyablePtr<DebugAnnotation_NestedValue> nested_value_;
+  std::string legacy_json_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<13> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 {
+
+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 unknown_fields_ == other.unknown_fields_
+   && iid_ == other.iid_
+   && 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 */:
+        field.get(&name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DebugAnnotationName::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DebugAnnotationName::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DebugAnnotationName::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, iid_);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    msg->AppendString(2, name_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && name_iid_ == other.name_iid_
+   && name_ == other.name_
+   && bool_value_ == other.bool_value_
+   && uint_value_ == other.uint_value_
+   && int_value_ == other.int_value_
+   && double_value_ == other.double_value_
+   && string_value_ == other.string_value_
+   && pointer_value_ == other.pointer_value_
+   && nested_value_ == other.nested_value_
+   && legacy_json_value_ == other.legacy_json_value_
+   && dict_entries_ == other.dict_entries_
+   && 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 */:
+        field.get(&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 6 /* string_value */:
+        field.get(&string_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 */:
+        field.get(&legacy_json_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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DebugAnnotation::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DebugAnnotation::Serialize(::protozero::Message* msg) const {
+  // Field 1: name_iid
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, name_iid_);
+  }
+
+  // Field 10: name
+  if (_has_field_[10]) {
+    msg->AppendString(10, name_);
+  }
+
+  // Field 2: bool_value
+  if (_has_field_[2]) {
+    msg->AppendTinyVarInt(2, bool_value_);
+  }
+
+  // Field 3: uint_value
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, uint_value_);
+  }
+
+  // Field 4: int_value
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, int_value_);
+  }
+
+  // Field 5: double_value
+  if (_has_field_[5]) {
+    msg->AppendFixed(5, double_value_);
+  }
+
+  // Field 6: string_value
+  if (_has_field_[6]) {
+    msg->AppendString(6, string_value_);
+  }
+
+  // Field 7: pointer_value
+  if (_has_field_[7]) {
+    msg->AppendVarInt(7, pointer_value_);
+  }
+
+  // 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]) {
+    msg->AppendString(9, legacy_json_value_);
+  }
+
+  // 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));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && nested_type_ == other.nested_type_
+   && dict_keys_ == other.dict_keys_
+   && dict_values_ == other.dict_values_
+   && array_values_ == other.array_values_
+   && int_value_ == other.int_value_
+   && double_value_ == other.double_value_
+   && bool_value_ == other.bool_value_
+   && 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();
+        field.get(&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 */:
+        field.get(&string_value_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DebugAnnotation_NestedValue::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DebugAnnotation_NestedValue::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DebugAnnotation_NestedValue::Serialize(::protozero::Message* msg) const {
+  // Field 1: nested_type
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, nested_type_);
+  }
+
+  // Field 2: dict_keys
+  for (auto& it : dict_keys_) {
+    msg->AppendString(2, it);
+  }
+
+  // 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]) {
+    msg->AppendVarInt(5, int_value_);
+  }
+
+  // Field 6: double_value
+  if (_has_field_[6]) {
+    msg->AppendFixed(6, double_value_);
+  }
+
+  // Field 7: bool_value
+  if (_has_field_[7]) {
+    msg->AppendTinyVarInt(7, bool_value_);
+  }
+
+  // Field 8: string_value
+  if (_has_field_[8]) {
+    msg->AppendString(8, string_value_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT 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 LogMessage : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSourceLocationIidFieldNumber = 1,
+    kBodyIidFieldNumber = 2,
+  };
+
+  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); }
+
+ private:
+  uint64_t source_location_iid_{};
+  uint64_t body_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_LOG_MESSAGE_PROTO_CPP_H_
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && iid_ == other.iid_
+   && 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 */:
+        field.get(&body_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string LogMessageBody::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> LogMessageBody::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void LogMessageBody::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, iid_);
+  }
+
+  // Field 2: body
+  if (_has_field_[2]) {
+    msg->AppendString(2, body_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && source_location_iid_ == other.source_location_iid_
+   && body_iid_ == other.body_iid_;
+}
+
+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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string LogMessage::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> LogMessage::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void LogMessage::Serialize(::protozero::Message* msg) const {
+  // Field 1: source_location_iid
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, source_location_iid_);
+  }
+
+  // Field 2: body_iid
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, body_iid_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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,
+  };
+
+  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); }
+
+ 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_{};
+
+  // 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_PROCESS_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && pid_ == other.pid_
+   && cmdline_ == other.cmdline_
+   && process_name_ == other.process_name_
+   && process_priority_ == other.process_priority_
+   && start_timestamp_ns_ == other.start_timestamp_ns_
+   && chrome_process_type_ == other.chrome_process_type_
+   && legacy_sort_index_ == other.legacy_sort_index_;
+}
+
+bool ProcessDescriptor::ParseFromArray(const void* raw, size_t size) {
+  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 /* pid */:
+        field.get(&pid_);
+        break;
+      case 2 /* cmdline */:
+        cmdline_.emplace_back();
+        field.get(&cmdline_.back());
+        break;
+      case 6 /* process_name */:
+        field.get(&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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ProcessDescriptor::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ProcessDescriptor::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ProcessDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: pid
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, pid_);
+  }
+
+  // Field 2: cmdline
+  for (auto& it : cmdline_) {
+    msg->AppendString(2, it);
+  }
+
+  // Field 6: process_name
+  if (_has_field_[6]) {
+    msg->AppendString(6, process_name_);
+  }
+
+  // Field 5: process_priority
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, process_priority_);
+  }
+
+  // Field 7: start_timestamp_ns
+  if (_has_field_[7]) {
+    msg->AppendVarInt(7, start_timestamp_ns_);
+  }
+
+  // Field 4: chrome_process_type
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, chrome_process_type_);
+  }
+
+  // Field 3: legacy_sort_index
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, legacy_sort_index_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && iid_ == other.iid_
+   && file_name_ == other.file_name_
+   && function_name_ == other.function_name_
+   && 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 */:
+        field.get(&file_name_);
+        break;
+      case 3 /* function_name */:
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SourceLocation::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SourceLocation::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, iid_);
+  }
+
+  // Field 2: file_name
+  if (_has_field_[2]) {
+    msg->AppendString(2, file_name_);
+  }
+
+  // Field 3: function_name
+  if (_has_field_[3]) {
+    msg->AppendString(3, function_name_);
+  }
+
+  // Field 4: line_number
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, line_number_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TaskExecution::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TaskExecution::Serialize(::protozero::Message* msg) const {
+  // Field 1: posted_from_iid
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, posted_from_iid_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && pid_ == other.pid_
+   && tid_ == other.tid_
+   && thread_name_ == other.thread_name_
+   && chrome_thread_type_ == other.chrome_thread_type_
+   && reference_timestamp_us_ == other.reference_timestamp_us_
+   && reference_thread_time_us_ == other.reference_thread_time_us_
+   && reference_thread_instruction_count_ == other.reference_thread_instruction_count_
+   && 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 */:
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ThreadDescriptor::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ThreadDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: pid
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, pid_);
+  }
+
+  // Field 2: tid
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, tid_);
+  }
+
+  // Field 5: thread_name
+  if (_has_field_[5]) {
+    msg->AppendString(5, thread_name_);
+  }
+
+  // Field 4: chrome_thread_type
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, chrome_thread_type_);
+  }
+
+  // Field 6: reference_timestamp_us
+  if (_has_field_[6]) {
+    msg->AppendVarInt(6, reference_timestamp_us_);
+  }
+
+  // Field 7: reference_thread_time_us
+  if (_has_field_[7]) {
+    msg->AppendVarInt(7, reference_thread_time_us_);
+  }
+
+  // Field 8: reference_thread_instruction_count
+  if (_has_field_[8]) {
+    msg->AppendVarInt(8, reference_thread_instruction_count_);
+  }
+
+  // Field 3: legacy_sort_index
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, legacy_sort_index_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && uuid_ == other.uuid_
+   && parent_uuid_ == other.parent_uuid_
+   && name_ == other.name_
+   && process_ == other.process_
+   && chrome_process_ == other.chrome_process_
+   && thread_ == other.thread_
+   && chrome_thread_ == other.chrome_thread_
+   && counter_ == other.counter_;
+}
+
+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 */:
+        field.get(&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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TrackDescriptor::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackDescriptor::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: uuid
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, uuid_);
+  }
+
+  // Field 5: parent_uuid
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, parent_uuid_);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    msg->AppendString(2, name_);
+  }
+
+  // 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));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 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 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 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 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 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 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 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,
+    kFlowIdsFieldNumber = 36,
+    kTerminatingFlowIdsFieldNumber = 42,
+    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,
+    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() 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() 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_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_;
+  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<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<47> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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/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/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 unknown_fields_ == other.unknown_fields_
+   && iid_ == other.iid_
+   && 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 */:
+        field.get(&name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string EventName::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EventName::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void EventName::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, iid_);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    msg->AppendString(2, name_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && iid_ == other.iid_
+   && 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 */:
+        field.get(&name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string EventCategory::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EventCategory::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void EventCategory::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, iid_);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    msg->AppendString(2, name_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && track_uuid_ == other.track_uuid_
+   && extra_counter_track_uuids_ == other.extra_counter_track_uuids_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEventDefaults::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackEventDefaults::Serialize(::protozero::Message* msg) const {
+  // Field 11: track_uuid
+  if (_has_field_[11]) {
+    msg->AppendVarInt(11, track_uuid_);
+  }
+
+  // Field 31: extra_counter_track_uuids
+  for (auto& it : extra_counter_track_uuids_) {
+    msg->AppendVarInt(31, it);
+  }
+
+  // Field 45: extra_double_counter_track_uuids
+  for (auto& it : extra_double_counter_track_uuids_) {
+    msg->AppendVarInt(45, it);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && category_iids_ == other.category_iids_
+   && categories_ == other.categories_
+   && name_iid_ == other.name_iid_
+   && name_ == other.name_
+   && type_ == other.type_
+   && track_uuid_ == other.track_uuid_
+   && counter_value_ == other.counter_value_
+   && double_counter_value_ == other.double_counter_value_
+   && extra_counter_track_uuids_ == other.extra_counter_track_uuids_
+   && extra_counter_values_ == other.extra_counter_values_
+   && extra_double_counter_track_uuids_ == other.extra_double_counter_track_uuids_
+   && extra_double_counter_values_ == other.extra_double_counter_values_
+   && flow_ids_ == other.flow_ids_
+   && terminating_flow_ids_ == other.terminating_flow_ids_
+   && debug_annotations_ == other.debug_annotations_
+   && task_execution_ == other.task_execution_
+   && log_message_ == other.log_message_
+   && cc_scheduler_state_ == other.cc_scheduler_state_
+   && chrome_user_event_ == other.chrome_user_event_
+   && chrome_keyed_service_ == other.chrome_keyed_service_
+   && chrome_legacy_ipc_ == other.chrome_legacy_ipc_
+   && chrome_histogram_sample_ == other.chrome_histogram_sample_
+   && chrome_latency_info_ == other.chrome_latency_info_
+   && chrome_frame_reporter_ == other.chrome_frame_reporter_
+   && chrome_application_state_info_ == other.chrome_application_state_info_
+   && chrome_renderer_scheduler_state_ == other.chrome_renderer_scheduler_state_
+   && chrome_window_handle_event_info_ == other.chrome_window_handle_event_info_
+   && chrome_content_settings_event_info_ == other.chrome_content_settings_event_info_
+   && source_location_ == other.source_location_
+   && source_location_iid_ == other.source_location_iid_
+   && chrome_message_pump_ == other.chrome_message_pump_
+   && chrome_mojo_event_info_ == other.chrome_mojo_event_info_
+   && timestamp_delta_us_ == other.timestamp_delta_us_
+   && timestamp_absolute_us_ == other.timestamp_absolute_us_
+   && thread_time_delta_us_ == other.thread_time_delta_us_
+   && thread_time_absolute_us_ == other.thread_time_absolute_us_
+   && thread_instruction_count_delta_ == other.thread_instruction_count_delta_
+   && thread_instruction_count_absolute_ == other.thread_instruction_count_absolute_
+   && 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_.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();
+        field.get(&categories_.back());
+        break;
+      case 10 /* name_iid */:
+        field.get(&name_iid_);
+        break;
+      case 23 /* name */:
+        field.get(&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 */:
+        flow_ids_.emplace_back();
+        field.get(&flow_ids_.back());
+        break;
+      case 42 /* 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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEvent::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackEvent::Serialize(::protozero::Message* msg) const {
+  // Field 3: category_iids
+  for (auto& it : category_iids_) {
+    msg->AppendVarInt(3, it);
+  }
+
+  // Field 22: categories
+  for (auto& it : categories_) {
+    msg->AppendString(22, it);
+  }
+
+  // Field 10: name_iid
+  if (_has_field_[10]) {
+    msg->AppendVarInt(10, name_iid_);
+  }
+
+  // Field 23: name
+  if (_has_field_[23]) {
+    msg->AppendString(23, name_);
+  }
+
+  // Field 9: type
+  if (_has_field_[9]) {
+    msg->AppendVarInt(9, type_);
+  }
+
+  // Field 11: track_uuid
+  if (_has_field_[11]) {
+    msg->AppendVarInt(11, track_uuid_);
+  }
+
+  // Field 30: counter_value
+  if (_has_field_[30]) {
+    msg->AppendVarInt(30, counter_value_);
+  }
+
+  // Field 44: double_counter_value
+  if (_has_field_[44]) {
+    msg->AppendFixed(44, double_counter_value_);
+  }
+
+  // Field 31: extra_counter_track_uuids
+  for (auto& it : extra_counter_track_uuids_) {
+    msg->AppendVarInt(31, it);
+  }
+
+  // Field 12: extra_counter_values
+  for (auto& it : extra_counter_values_) {
+    msg->AppendVarInt(12, it);
+  }
+
+  // Field 45: extra_double_counter_track_uuids
+  for (auto& it : extra_double_counter_track_uuids_) {
+    msg->AppendVarInt(45, it);
+  }
+
+  // Field 46: extra_double_counter_values
+  for (auto& it : extra_double_counter_values_) {
+    msg->AppendFixed(46, it);
+  }
+
+  // Field 36: flow_ids
+  for (auto& it : flow_ids_) {
+    msg->AppendVarInt(36, it);
+  }
+
+  // Field 42: terminating_flow_ids
+  for (auto& it : terminating_flow_ids_) {
+    msg->AppendVarInt(42, it);
+  }
+
+  // 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 33: source_location
+  if (_has_field_[33]) {
+    (*source_location_).Serialize(msg->BeginNestedMessage<::protozero::Message>(33));
+  }
+
+  // Field 34: source_location_iid
+  if (_has_field_[34]) {
+    msg->AppendVarInt(34, source_location_iid_);
+  }
+
+  // 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]) {
+    msg->AppendVarInt(1, timestamp_delta_us_);
+  }
+
+  // Field 16: timestamp_absolute_us
+  if (_has_field_[16]) {
+    msg->AppendVarInt(16, timestamp_absolute_us_);
+  }
+
+  // Field 2: thread_time_delta_us
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, thread_time_delta_us_);
+  }
+
+  // Field 17: thread_time_absolute_us
+  if (_has_field_[17]) {
+    msg->AppendVarInt(17, thread_time_absolute_us_);
+  }
+
+  // Field 8: thread_instruction_count_delta
+  if (_has_field_[8]) {
+    msg->AppendVarInt(8, thread_instruction_count_delta_);
+  }
+
+  // Field 20: thread_instruction_count_absolute
+  if (_has_field_[20]) {
+    msg->AppendVarInt(20, thread_instruction_count_absolute_);
+  }
+
+  // Field 6: legacy_event
+  if (_has_field_[6]) {
+    (*legacy_event_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && name_iid_ == other.name_iid_
+   && phase_ == other.phase_
+   && duration_us_ == other.duration_us_
+   && thread_duration_us_ == other.thread_duration_us_
+   && thread_instruction_delta_ == other.thread_instruction_delta_
+   && unscoped_id_ == other.unscoped_id_
+   && local_id_ == other.local_id_
+   && global_id_ == other.global_id_
+   && id_scope_ == other.id_scope_
+   && use_async_tts_ == other.use_async_tts_
+   && bind_id_ == other.bind_id_
+   && bind_to_enclosing_ == other.bind_to_enclosing_
+   && flow_direction_ == other.flow_direction_
+   && instant_event_scope_ == other.instant_event_scope_
+   && pid_override_ == other.pid_override_
+   && 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 */:
+        field.get(&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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEvent_LegacyEvent::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackEvent_LegacyEvent::Serialize(::protozero::Message* msg) const {
+  // Field 1: name_iid
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, name_iid_);
+  }
+
+  // Field 2: phase
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, phase_);
+  }
+
+  // Field 3: duration_us
+  if (_has_field_[3]) {
+    msg->AppendVarInt(3, duration_us_);
+  }
+
+  // Field 4: thread_duration_us
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, thread_duration_us_);
+  }
+
+  // Field 15: thread_instruction_delta
+  if (_has_field_[15]) {
+    msg->AppendVarInt(15, thread_instruction_delta_);
+  }
+
+  // Field 6: unscoped_id
+  if (_has_field_[6]) {
+    msg->AppendVarInt(6, unscoped_id_);
+  }
+
+  // Field 10: local_id
+  if (_has_field_[10]) {
+    msg->AppendVarInt(10, local_id_);
+  }
+
+  // Field 11: global_id
+  if (_has_field_[11]) {
+    msg->AppendVarInt(11, global_id_);
+  }
+
+  // Field 7: id_scope
+  if (_has_field_[7]) {
+    msg->AppendString(7, id_scope_);
+  }
+
+  // Field 9: use_async_tts
+  if (_has_field_[9]) {
+    msg->AppendTinyVarInt(9, use_async_tts_);
+  }
+
+  // Field 8: bind_id
+  if (_has_field_[8]) {
+    msg->AppendVarInt(8, bind_id_);
+  }
+
+  // Field 12: bind_to_enclosing
+  if (_has_field_[12]) {
+    msg->AppendTinyVarInt(12, bind_to_enclosing_);
+  }
+
+  // Field 13: flow_direction
+  if (_has_field_[13]) {
+    msg->AppendVarInt(13, flow_direction_);
+  }
+
+  // Field 14: instant_event_scope
+  if (_has_field_[14]) {
+    msg->AppendVarInt(14, instant_event_scope_);
+  }
+
+  // Field 18: pid_override
+  if (_has_field_[18]) {
+    msg->AppendVarInt(18, pid_override_);
+  }
+
+  // Field 19: tid_override
+  if (_has_field_[19]) {
+    msg->AppendVarInt(19, tid_override_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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.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/packages_list_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/sys_stats/sys_stats_config.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/data_source_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/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/android/android_log.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/packages_list.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/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/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/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/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/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/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/lowmemorykiller.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/oom.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/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/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/sync.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/thermal.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/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/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/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/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_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+using uid_t = unsigned int;
+#endif
+
+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;
+
+// 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().
+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 uid_t kInvalidUid = static_cast<uid_t>(-1);
+
+constexpr uint32_t kDefaultFlushTimeoutMs = 5000;
+
+}  // 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
+
+// This is a single-thread write interface that allows to write protobufs
+// directly into the tracing shared buffer without making any copies.
+// It takes care of acquiring and releasing chunks from the
+// SharedMemoryArbiter and splitting protos over chunks.
+// 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. 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 PERFETTO_EXPORT TraceWriter : public TraceWriterBase {
+ public:
+  using TracePacketHandle =
+      protozero::MessageHandle<protos::pbzero::TracePacket>;
+
+  TraceWriter();
+  ~TraceWriter() override;
+
+  // Returns a handle to the root proto message for the trace. The message will
+  // be finalized either by calling directly handle.Finalize() or by letting the
+  // handle go out of scope. 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 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.
+  TracePacketHandle NewTracePacket() override = 0;
+
+  // Commits the data pending for the current chunk into the shared memory
+  // buffer and sends a CommitDataRequest() to the service. 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).
+  // 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 = 0;
+
+  virtual WriterID writer_id() const = 0;
+
+  // Bytes written since creation. Is not reset when new chunks are acquired.
+  virtual uint64_t written() const override = 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/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 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(). Its 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());
+}
+
+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 in the Chunk is prefixed by a 4 bytes redundant VarInt
+  // (see proto_utils.h) stating its size.
+  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)            |
+  //        +------------------------+
+  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};
+
+  // 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;
+    }
+
+    // Increases |packets.count| to the given |packet_count|, but only if
+    // |packet_count| is larger than the current value of |packets.count|.
+    // Returns the new packet count. Same atomicity guarantees as
+    // IncrementPacketCount().
+    uint16_t IncreasePacketCountTo(uint16_t packet_count) {
+      ChunkHeader* chunk_header = header();
+      auto packets = chunk_header->packets.load(std::memory_order_relaxed);
+      if (packets.count < packet_count)
+        packets.count = packet_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;
+  };
+
+  // Construct an instance from an existing shared memory buffer.
+  SharedMemoryABI(uint8_t* start, size_t size, size_t page_size);
+  SharedMemoryABI();
+
+  void Initialize(uint8_t* start, size_t size, size_t page_size);
+
+  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);
+
+  // 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;
+  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
+
+// static
+constexpr uint32_t SharedMemoryABI::kNumChunksForLayout[];
+constexpr const char* SharedMemoryABI::kChunkStateStr[];
+constexpr const size_t SharedMemoryABI::kInvalidPageIdx;
+constexpr const size_t SharedMemoryABI::kMinPageSize;
+constexpr const size_t SharedMemoryABI::kMaxPageSize;
+constexpr const size_t SharedMemoryABI::kPacketSizeDropPacket;
+
+SharedMemoryABI::SharedMemoryABI() = default;
+
+SharedMemoryABI::SharedMemoryABI(uint8_t* start,
+                                 size_t size,
+                                 size_t page_size) {
+  Initialize(start, size, page_size);
+}
+
+void SharedMemoryABI::Initialize(uint8_t* start,
+                                 size_t size,
+                                 size_t page_size) {
+  start_ = start;
+  size_ = size;
+  page_size_ = page_size;
+  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 =
+        ((layout >> (chunk_idx * kChunkShift)) & kChunkMask);
+
+    // 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).
+    ChunkState expected_chunk_state;
+    if (desired_chunk_state == kChunkComplete) {
+      expected_chunk_state = kChunkBeingWritten;
+    } else {
+      expected_chunk_state = 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/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 SharedMemory {
+ public:
+  class PERFETTO_EXPORT 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) 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/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.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;
+
+// Exposed for testing.
+std::string GetBugreportPath();
+
+// 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 ProducerEndpoint {
+ public:
+  virtual ~ProducerEndpoint();
+
+  // 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 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 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;
+
+  // 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) = 0;
+
+  // 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.
+
+// 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 TracingService {
+ public:
+  using ProducerEndpoint = perfetto::ProducerEndpoint;
+  using ConsumerEndpoint = perfetto::ConsumerEndpoint;
+
+  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 .
+  static std::unique_ptr<TracingService> CreateInstance(
+      std::unique_ptr<SharedMemory::Factory>,
+      base::TaskRunner*);
+
+  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*,
+      uid_t uid,
+      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/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 SharedMemoryArbiter {
+ public:
+  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(), 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. Only supported
+  // if the arbiter was created using CreateUnbound(), and may be called while
+  // the arbiter is unbound.
+  //
+  // 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 targets 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,
+      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);
+};
+
+}  // 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.
+//
+// When the arbiter is created using CreateUnboundInstance(), the following
+// state transitions are possible:
+//
+//   [ !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*,
+                          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;
+  }
+
+  // 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();
+
+  const bool initially_bound_;
+
+  // Only accessed on |task_runner_| after the producer endpoint was bound.
+  TracingService::ProducerEndpoint* producer_endpoint_ = nullptr;
+
+  // --- 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_;
+
+  // 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) {
+    PERFETTO_DCHECK(empty() || last_->chunk_id != chunk_id ||
+                    offset >= last_->offset + sizeof(Patch::PatchContent));
+    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/tracing/core/trace_writer.h for docs.
+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 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(); }
+  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;
+
+  // 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.
+  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;
+
+  // Points to the size field of the last packet we wrote to the current chunk.
+  // If the chunk was already returned, this is reset to |nullptr|.
+  uint8_t* last_packet_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_;
+};
+
+}  // 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 "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
+constexpr BufferID SharedMemoryArbiterImpl::kInvalidBufferId;
+
+// static
+std::unique_ptr<SharedMemoryArbiter> SharedMemoryArbiter::CreateInstance(
+    SharedMemory* shared_memory,
+    size_t page_size,
+    TracingService::ProducerEndpoint* producer_endpoint,
+    base::TaskRunner* task_runner) {
+  return std::unique_ptr<SharedMemoryArbiterImpl>(
+      new SharedMemoryArbiterImpl(shared_memory->start(), shared_memory->size(),
+                                  page_size, producer_endpoint, task_runner));
+}
+
+// static
+std::unique_ptr<SharedMemoryArbiter> SharedMemoryArbiter::CreateUnboundInstance(
+    SharedMemory* shared_memory,
+    size_t page_size) {
+  return std::unique_ptr<SharedMemoryArbiterImpl>(new SharedMemoryArbiterImpl(
+      shared_memory->start(), shared_memory->size(), page_size,
+      /*producer_endpoint=*/nullptr, /*task_runner=*/nullptr));
+}
+
+SharedMemoryArbiterImpl::SharedMemoryArbiterImpl(
+    void* start,
+    size_t size,
+    size_t page_size,
+    TracingService::ProducerEndpoint* producer_endpoint,
+    base::TaskRunner* task_runner)
+    : initially_bound_(task_runner && producer_endpoint),
+      producer_endpoint_(producer_endpoint),
+      task_runner_(task_runner),
+      shmem_abi_(reinterpret_cast<uint8_t*>(start), size, page_size),
+      active_writer_ids_(kMaxWriterID),
+      fully_bound_(initially_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.
+  // If initially 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(initially_bound_ ||
+                  buffer_exhausted_policy == BufferExhaustedPolicy::kDrop);
+
+  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 = 100;
+
+  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_);
+
+      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 exhaused, returning invalid Chunk!");
+      return Chunk();
+    }
+
+    PERFETTO_DCHECK(initially_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;
+      }
+    }
+
+    // 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;
+      // 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.
+      CommitDataRequest::ChunksToMove* ctm =
+          commit_data_req_->add_chunks_to_move();
+      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_->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)
+          continue;
+
+        SharedMemoryABI::Chunk chunk =
+            shmem_abi_.GetChunkUnchecked(ctm.page(), layout, ctm.chunk());
+        shmem_abi_.ReleaseChunkAsComplete(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) {
+  PERFETTO_CHECK(!initially_bound_);
+  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());
+  PERFETTO_CHECK(!initially_bound_);
+
+  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);
+  PERFETTO_CHECK(!initially_bound_);
+
+  std::unique_lock<std::mutex> scoped_lock(lock_);
+
+  // We should already be bound to an endpoint, but not fully bound.
+  PERFETTO_CHECK(!fully_bound_);
+  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) {
+  PERFETTO_CHECK(!initially_bound_);
+
+  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;
+  }
+
+  PERFETTO_CHECK(!fully_bound_);
+
+  // 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);
+
+  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;
+    } 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_;
+    }
+  }  // 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;
+      });
+  return fully_bound_;
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/trace_packet.cc
+// 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 <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 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();
+
+ 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_).
+  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.
+ */
+
+// 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;
+  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 "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;
+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 DCHECK 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::Flush(std::function<void()> callback) {
+  // Flush() cannot be called in the middle of a TracePacket.
+  PERFETTO_CHECK(cur_packet_->is_finalized());
+
+  if (cur_chunk_.is_valid()) {
+    shmem_arbiter_->ReturnCompletedChunk(std::move(cur_chunk_), target_buffer_,
+                                         &patch_list_);
+  } 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});
+
+  // |last_packet_size_field_| might have pointed into the chunk we returned.
+  last_packet_size_field_ = 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());
+
+  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_packet_->set_size_field(header);
+  last_packet_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 = cur_chunk_.IncrementPacketCount();
+    reached_max_packets_per_chunk_ =
+        new_packet_count == ChunkHeader::Packets::kMaxCount;
+
+    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);
+    }
+  }
+
+  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;
+    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_packet_->size_field());
+
+      // Reset the size field, since we should not write the current packet's
+      // size anymore after this.
+      cur_packet_->set_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_ && last_packet_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());
+
+      // |last_packet_size_field_| should point within |cur_chunk_|'s payload.
+      PERFETTO_DCHECK(last_packet_size_field_ >= cur_chunk_.payload_begin() &&
+                      last_packet_size_field_ + kMessageLengthFieldSize <=
+                          cur_chunk_.end());
+
+      WriteRedundantVarInt(SharedMemoryABI::kPacketSizeDropPacket,
+                           last_packet_size_field_);
+    }
+
+    if (cur_chunk_.is_valid()) {
+      shmem_arbiter_->ReturnCompletedChunk(std::move(cur_chunk_),
+                                           target_buffer_, &patch_list_);
+    }
+
+    drop_packets_ = true;
+    cur_chunk_ = SharedMemoryABI::Chunk();  // Reset to an invalid chunk.
+    reached_max_packets_per_chunk_ = false;
+    retry_new_chunk_after_packet_ = false;
+    last_packet_size_field_ = nullptr;
+
+    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_packet_->inc_size_already_written(partial_size);
+    cur_chunk_.SetFlag(ChunkHeader::kLastPacketContinuesOnNextChunk);
+    WriteRedundantVarInt(partial_size, cur_packet_->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.
+    // TODO(primiano): add tests to cover this logic.
+    bool chunk_needs_patching = false;
+    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) {
+        auto offset =
+            static_cast<uint16_t>(cur_hdr - cur_chunk_.payload_begin());
+        const ChunkID cur_chunk_id =
+            cur_chunk_.header()->chunk_id.load(std::memory_order_relaxed);
+        Patch* patch = patch_list_.emplace_back(cur_chunk_id, offset);
+        nested_msg->set_size_field(&patch->size_field[0]);
+        chunk_needs_patching = true;
+      } 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 (chunk_needs_patching)
+      cur_chunk_.SetFlag(ChunkHeader::kChunkNeedsPatching);
+  }  // if(fragmenting_packet)
+
+  if (cur_chunk_.is_valid()) {
+    // ReturnCompletedChunk will consume the first patched entries from
+    // |patch_list_| and shrink it.
+    shmem_arbiter_->ReturnCompletedChunk(std::move(cur_chunk_), target_buffer_,
+                                         &patch_list_);
+  }
+
+  // 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);
+  last_packet_size_field_ = nullptr;
+
+  uint8_t* payload_begin = cur_chunk_.payload_begin();
+  if (fragmenting_packet_) {
+    cur_packet_->set_size_field(payload_begin);
+    last_packet_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()};
+}
+
+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/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 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;
+};
+
+}  // 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/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 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;
+
+  // 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) = 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;
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/console_interceptor.cc
+// 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 {
+
+enum ConsoleConfig_Output : int32_t;
+
+enum ConsoleConfig_Output : int32_t {
+  ConsoleConfig_Output_OUTPUT_UNSPECIFIED = 0,
+  ConsoleConfig_Output_OUTPUT_STDOUT = 1,
+  ConsoleConfig_Output_OUTPUT_STDERR = 2,
+};
+
+const ConsoleConfig_Output ConsoleConfig_Output_MIN = ConsoleConfig_Output_OUTPUT_UNSPECIFIED;
+const ConsoleConfig_Output ConsoleConfig_Output_MAX = ConsoleConfig_Output_OUTPUT_STDERR;
+
+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,
+  };
+  using Output = ::perfetto::protos::pbzero::ConsoleConfig_Output;
+  static const Output OUTPUT_UNSPECIFIED = ConsoleConfig_Output_OUTPUT_UNSPECIFIED;
+  static const Output OUTPUT_STDOUT = ConsoleConfig_Output_OUTPUT_STDOUT;
+  static const Output OUTPUT_STDERR = ConsoleConfig_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Output kOutput() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EnableColors kEnableColors() { return {}; }
+  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/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,
+  };
+
+  using FieldMetadata_TimestampClockId =
+    ::protozero::proto_utils::FieldMetadata<
+      58,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracePacketDefaults>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TimestampClockId kTimestampClockId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrackEventDefaults kTrackEventDefaults() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PerfSampleDefaults kPerfSampleDefaults() { return {}; }
+  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/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 {
+
+enum ProcessDescriptor_ChromeProcessType : int32_t;
+
+enum ProcessDescriptor_ChromeProcessType : int32_t {
+  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,
+};
+
+const ProcessDescriptor_ChromeProcessType ProcessDescriptor_ChromeProcessType_MIN = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
+const ProcessDescriptor_ChromeProcessType ProcessDescriptor_ChromeProcessType_MAX = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER;
+
+class ProcessDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*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(); }
+};
+
+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,
+  };
+  using ChromeProcessType = ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType;
+  static const ChromeProcessType PROCESS_UNSPECIFIED = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
+  static const ChromeProcessType PROCESS_BROWSER = ProcessDescriptor_ChromeProcessType_PROCESS_BROWSER;
+  static const ChromeProcessType PROCESS_RENDERER = ProcessDescriptor_ChromeProcessType_PROCESS_RENDERER;
+  static const ChromeProcessType PROCESS_UTILITY = ProcessDescriptor_ChromeProcessType_PROCESS_UTILITY;
+  static const ChromeProcessType PROCESS_ZYGOTE = ProcessDescriptor_ChromeProcessType_PROCESS_ZYGOTE;
+  static const ChromeProcessType PROCESS_SANDBOX_HELPER = ProcessDescriptor_ChromeProcessType_PROCESS_SANDBOX_HELPER;
+  static const ChromeProcessType PROCESS_GPU = ProcessDescriptor_ChromeProcessType_PROCESS_GPU;
+  static const ChromeProcessType PROCESS_PPAPI_PLUGIN = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_PLUGIN;
+  static const ChromeProcessType PROCESS_PPAPI_BROKER = ProcessDescriptor_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cmdline kCmdline() { return {}; }
+  void add_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessName kProcessName() { return {}; }
+  void set_process_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProcessName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessPriority kProcessPriority() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StartTimestampNs kStartTimestampNs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeProcessType kChromeProcessType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LegacySortIndex kLegacySortIndex() { return {}; }
+  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/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 {
+
+enum ThreadDescriptor_ChromeThreadType : int32_t;
+
+enum ThreadDescriptor_ChromeThreadType : int32_t {
+  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,
+};
+
+const ThreadDescriptor_ChromeThreadType ThreadDescriptor_ChromeThreadType_MIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
+const ThreadDescriptor_ChromeThreadType ThreadDescriptor_ChromeThreadType_MAX = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER;
+
+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,
+  };
+  using ChromeThreadType = ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType;
+  static const ChromeThreadType CHROME_THREAD_UNSPECIFIED = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
+  static const ChromeThreadType CHROME_THREAD_MAIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MAIN;
+  static const ChromeThreadType CHROME_THREAD_IO = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_IO;
+  static const ChromeThreadType CHROME_THREAD_POOL_BG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_WORKER;
+  static const ChromeThreadType CHROME_THREAD_POOL_FG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FG_WORKER;
+  static const ChromeThreadType CHROME_THREAD_POOL_FB_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FB_BLOCKING;
+  static const ChromeThreadType CHROME_THREAD_POOL_BG_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_BLOCKING;
+  static const ChromeThreadType CHROME_THREAD_POOL_SERVICE = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_SERVICE;
+  static const ChromeThreadType CHROME_THREAD_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR;
+  static const ChromeThreadType CHROME_THREAD_VIZ_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_VIZ_COMPOSITOR;
+  static const ChromeThreadType CHROME_THREAD_COMPOSITOR_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR_WORKER;
+  static const ChromeThreadType CHROME_THREAD_SERVICE_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SERVICE_WORKER;
+  static const ChromeThreadType CHROME_THREAD_MEMORY_INFRA = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MEMORY_INFRA;
+  static const ChromeThreadType CHROME_THREAD_SAMPLING_PROFILER = ThreadDescriptor_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tid kTid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadName kThreadName() { return {}; }
+  void set_thread_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ThreadName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeThreadType kChromeThreadType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReferenceTimestampUs kReferenceTimestampUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReferenceThreadTimeUs kReferenceThreadTimeUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReferenceThreadInstructionCount kReferenceThreadInstructionCount() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LegacySortIndex kLegacySortIndex() { return {}; }
+  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.
+/*
+ * 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"
+
+// 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/optional.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/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.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/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"
+
+#include <algorithm>
+#include <cmath>
+#include <tuple>
+
+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_;
+  base::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_ =
+      base::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{};
+  ssize_t written = 0;
+  if (tls.use_colors) {
+    written = snprintf(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 = snprintf(message_prefix.data(), message_prefix.size(), "%-*.*s",
+                       title_width + 2, title_width, title.data());
+  }
+  if (written < 0)
+    written = message_prefix.size();
+  track.user_data.assign(message_prefix.begin(),
+                         message_prefix.begin() + 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
+  protos::pbzero::ConsoleConfig::Decoder config(
+      args.config.interceptor_config().console_config_raw());
+  if (config.has_enable_colors())
+    use_colors = config.enable_colors();
+  if (config.output() == protos::pbzero::ConsoleConfig::OUTPUT_STDOUT) {
+    fd = STDOUT_FILENO;
+  } else if (config.output() == protos::pbzero::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"
+
+namespace perfetto {
+
+DataSourceBase::StopArgs::~StopArgs() = default;
+DataSourceBase::~DataSourceBase() = default;
+void DataSourceBase::OnSetup(const SetupArgs&) {}
+void DataSourceBase::OnStart(const StartArgs&) {}
+void DataSourceBase::OnStop(const StopArgs&) {}
+
+}  // 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.context_);
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/event_context.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/event_context.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(
+    EventContext::TracePacketHandle trace_packet,
+    internal::TrackEventIncrementalState* incremental_state)
+    : trace_packet_(std::move(trace_packet)),
+      event_(trace_packet_->set_track_event()),
+      incremental_state_(incremental_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_LIKELY(serialized_interned_data.empty()))
+    return;
+
+  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();
+}
+
+}  // 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 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();
+}
+
+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 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->producer_->OnConnect();
+    });
+  }
+  ~UnsupportedProducerEndpoint() override { producer_->OnDisconnect(); }
+
+  void RegisterDataSource(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 {
+    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 = BufferExhaustedPolicy::kDefault) 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 { callback(); }
+
+ private:
+  Producer* const producer_;
+  base::TaskRunner* const task_runner_;
+  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 = base::ScopedFile()) override {}
+  void ChangeTraceConfig(const TraceConfig&) override {}
+
+  void StartTracing() override {}
+  void DisableTracing() override {}
+
+  void Flush(uint32_t /*timeout_ms*/, FlushCallback callback) 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 {}
+
+ 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,
+                          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;
+
+ 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,
+                                          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();
+}
+
+}  // 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 <list>
+#include <map>
+#include <memory>
+#include <vector>
+
+// 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/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 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;
+
+  static void InitializeInstance(const TracingInitArgs&);
+
+  // TracingMuxer implementation.
+  bool RegisterDataSource(const DataSourceDescriptor&,
+                          DataSourceFactory,
+                          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;
+
+  std::unique_ptr<TracingSession> CreateTracingSession(BackendType);
+
+  // 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 StopDataSource_AsyncEnd(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:
+  // 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);
+    ~ProducerImpl() override;
+
+    void Initialize(std::unique_ptr<ProducerEndpoint> endpoint);
+    void RegisterDataSource(const DataSourceDescriptor&,
+                            DataSourceFactory,
+                            DataSourceStaticState*);
+
+    // perfetto::Producer implementation.
+    void OnConnect() override;
+    void OnDisconnect() override;
+    void OnTracingSetup() override;
+    void SetupDataSource(DataSourceInstanceID,
+                         const DataSourceConfig&) override;
+    void StartDataSource(DataSourceInstanceID,
+                         const DataSourceConfig&) override;
+    void StopDataSource(DataSourceInstanceID) override;
+    void Flush(FlushRequestID, const DataSourceInstanceID*, size_t) override;
+    void ClearIncrementalState(const DataSourceInstanceID*, size_t) override;
+
+    void SweepDeadServices();
+
+    PERFETTO_THREAD_CHECKER(thread_checker_)
+    TracingMuxerImpl* const muxer_;
+    TracingBackendId const backend_id_;
+    bool connected_ = false;
+    uint32_t connection_id_ = 0;
+
+    const uint32_t shmem_batch_commits_duration_ms_ = 0;
+
+    // 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_;
+
+    // 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,
+                 TracingBackendId,
+                 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 NotifyStartComplete();
+    void NotifyError(const TracingError&);
+    void NotifyStopComplete();
+
+    // Will eventually inform the |muxer_| when it is safe to remove |this|.
+    void Disconnect();
+
+    TracingMuxerImpl* const muxer_;
+    BackendType const backend_type_;
+    TracingBackendId const backend_id_;
+    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_;
+  };
+
+  struct RegisteredDataSource {
+    DataSourceDescriptor descriptor;
+    DataSourceFactory factory{};
+    DataSourceStaticState* static_state = nullptr;
+  };
+
+  struct RegisteredInterceptor {
+    protos::gen::InterceptorDescriptor descriptor;
+    InterceptorFactory factory{};
+    InterceptorBase::TLSFactory tls_factory{};
+    InterceptorBase::TracePacketCallback packet_callback{};
+  };
+
+  struct RegisteredBackend {
+    // Backends are supposed to have static lifetime.
+    TracingBackend* backend = nullptr;
+    TracingBackendId id = 0;
+    BackendType type{};
+
+    TracingBackend::ConnectProducerArgs producer_conn_args;
+    std::unique_ptr<ProducerImpl> producer;
+
+    // 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;
+  };
+
+  explicit TracingMuxerImpl(const TracingInitArgs&);
+  void Initialize(const TracingInitArgs& args);
+  ConsumerImpl* FindConsumer(TracingSessionGlobalID session_id);
+  void InitializeConsumer(TracingSessionGlobalID session_id);
+  void OnConsumerDisconnected(ConsumerImpl* consumer);
+  void OnProducerDisconnected(ProducerImpl* producer);
+
+  struct FindDataSourceRes {
+    FindDataSourceRes() = default;
+    FindDataSourceRes(DataSourceStaticState* a, DataSourceState* b, uint32_t c)
+        : static_state(a), internal_state(b), instance_idx(c) {}
+    explicit operator bool() const { return !!internal_state; }
+
+    DataSourceStaticState* static_state = nullptr;
+    DataSourceState* internal_state = nullptr;
+    uint32_t instance_idx = 0;
+  };
+  FindDataSourceRes FindDataSource(TracingBackendId, DataSourceInstanceID);
+
+  std::unique_ptr<base::TaskRunner> task_runner_;
+  std::vector<RegisteredDataSource> data_sources_;
+  std::vector<RegisteredBackend> backends_;
+  std::vector<RegisteredInterceptor> interceptors_;
+  TracingPolicy* policy_ = nullptr;
+
+  std::atomic<TracingSessionGlobalID> next_tracing_session_id_{};
+
+  // 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};
+
+  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 <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/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 "protos/perfetto/config/interceptor_config.gen.h"
+
+// gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_fake.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <io.h>  // For dup()
+#else
+#include <unistd.h>  // For dup()
+#endif
+
+namespace perfetto {
+namespace internal {
+
+namespace {
+
+// 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;
+};
+
+uint64_t ComputeConfigHash(const DataSourceConfig& config) {
+  base::Hash hasher;
+  std::string config_bytes = config.SerializeAsString();
+  hasher.Update(config_bytes.data(), config_bytes.size());
+  return hasher.digest();
+}
+
+}  // namespace
+
+// ----- Begin of TracingMuxerImpl::ProducerImpl
+TracingMuxerImpl::ProducerImpl::ProducerImpl(
+    TracingMuxerImpl* muxer,
+    TracingBackendId backend_id,
+    uint32_t shmem_batch_commits_duration_ms)
+    : muxer_(muxer),
+      backend_id_(backend_id),
+      shmem_batch_commits_duration_ms_(shmem_batch_commits_duration_ms) {}
+
+TracingMuxerImpl::ProducerImpl::~ProducerImpl() = default;
+
+void TracingMuxerImpl::ProducerImpl::Initialize(
+    std::unique_ptr<ProducerEndpoint> endpoint) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DCHECK(!connected_);
+  connection_id_++;
+
+  // 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) {
+    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_);
+  connected_ = true;
+  muxer_->UpdateDataSourcesOnAllBackends();
+}
+
+void TracingMuxerImpl::ProducerImpl::OnDisconnect() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  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();
+  // Keep the old service around as a dead connection in case it has active
+  // trace writers. We can't clear |service_| here because other threads may be
+  // concurrently creating new trace writers. The reconnection below will
+  // atomically swap the new service in place of the old one.
+  dead_services_.push_back(service_);
+  // Try reconnecting the producer.
+  muxer_->OnProducerDisconnected(this);
+}
+
+void TracingMuxerImpl::ProducerImpl::OnTracingSetup() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  service_->MaybeSharedMemoryArbiter()->SetBatchCommitsDuration(
+      shmem_batch_commits_duration_ms_);
+}
+
+void TracingMuxerImpl::ProducerImpl::SetupDataSource(
+    DataSourceInstanceID id,
+    const DataSourceConfig& cfg) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  muxer_->SetupDataSource(backend_id_, connection_id_, id, cfg);
+}
+
+void TracingMuxerImpl::ProducerImpl::StartDataSource(DataSourceInstanceID id,
+                                                     const DataSourceConfig&) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  muxer_->StartDataSource(backend_id_, id);
+  service_->NotifyDataSourceStarted(id);
+}
+
+void TracingMuxerImpl::ProducerImpl::StopDataSource(DataSourceInstanceID id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  muxer_->StopDataSource_AsyncBegin(backend_id_, id);
+}
+
+void TracingMuxerImpl::ProducerImpl::Flush(FlushRequestID flush_id,
+                                           const DataSourceInstanceID*,
+                                           size_t) {
+  // Flush is not plumbed for now, we just ack straight away.
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  service_->NotifyFlushComplete(flush_id);
+}
+
+void TracingMuxerImpl::ProducerImpl::ClearIncrementalState(
+    const DataSourceInstanceID* instances,
+    size_t instance_count) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (size_t inst_idx = 0; inst_idx < instance_count; inst_idx++) {
+    muxer_->ClearDataSourceIncrementalState(backend_id_, instances[inst_idx]);
+  }
+}
+
+void 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;
+  }
+}
+
+// ----- End of TracingMuxerImpl::ProducerImpl methods.
+
+// ----- Begin of TracingMuxerImpl::ConsumerImpl
+TracingMuxerImpl::ConsumerImpl::ConsumerImpl(TracingMuxerImpl* muxer,
+                                             BackendType backend_type,
+                                             TracingBackendId backend_id,
+                                             TracingSessionGlobalID session_id)
+    : muxer_(muxer),
+      backend_type_(backend_type),
+      backend_id_(backend_id),
+      session_id_(session_id) {}
+
+TracingMuxerImpl::ConsumerImpl::~ConsumerImpl() = default;
+
+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 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::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
+
+// 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); });
+}
+
+void TracingMuxerImpl::Initialize(const TracingInitArgs& args) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);  // Rebind the thread checker.
+
+  policy_ = args.tracing_policy;
+
+  auto add_backend = [this, &args](TracingBackend* 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("Backend creation failed, type %d", static_cast<int>(type));
+      return;
+    }
+    TracingBackendId backend_id = backends_.size();
+    backends_.emplace_back();
+    RegisteredBackend& rb = backends_.back();
+    rb.backend = backend;
+    rb.id = backend_id;
+    rb.type = type;
+    rb.producer.reset(new ProducerImpl(this, backend_id,
+                                       args.shmem_batch_commits_duration_ms));
+    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->Initialize(rb.backend->ConnectProducer(rb.producer_conn_args));
+  };
+
+  if (args.backends & kSystemBackend) {
+    PERFETTO_CHECK(args.system_backend_factory_);
+    add_backend(args.system_backend_factory_(), kSystemBackend);
+  }
+
+  if (args.backends & kInProcessBackend) {
+    PERFETTO_CHECK(args.in_process_backend_factory_);
+    add_backend(args.in_process_backend_factory_(), kInProcessBackend);
+  }
+
+  if (args.backends & kCustomBackend) {
+    PERFETTO_CHECK(args.custom_backend);
+    add_backend(args.custom_backend, kCustomBackend);
+  }
+
+  if (args.backends & ~(kSystemBackend | kInProcessBackend | kCustomBackend)) {
+    PERFETTO_FATAL("Unsupported tracing backend type");
+  }
+
+  // Fallback backend for consumer creation for an unsupported backend type.
+  // This backend simply fails any attempt to start a tracing session.
+  // NOTE: This backend instance has to be added last.
+  add_backend(internal::TracingBackendFake::GetInstance(),
+              BackendType::kUnspecifiedBackend);
+}
+
+// Can be called from any thread (but not concurrently).
+bool TracingMuxerImpl::RegisterDataSource(
+    const DataSourceDescriptor& descriptor,
+    DataSourceFactory factory,
+    DataSourceStaticState* static_state) {
+  // Ignore repeated registrations.
+  if (static_state->index != kMaxDataSources)
+    return true;
+
+  static std::atomic<uint32_t> last_id{};
+  uint32_t new_index = last_id++;
+  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;
+
+  task_runner_->PostTask([this, descriptor, factory, static_state] {
+    data_sources_.emplace_back();
+    RegisteredDataSource& rds = data_sources_.back();
+    rds.descriptor = descriptor;
+    rds.factory = factory;
+    rds.static_state = static_state;
+    UpdateDataSourcesOnAllBackends();
+  });
+  return true;
+}
+
+// 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") {
+          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;
+      });
+}
+
+// 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_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Setting up data source %" PRIu64 " %s", instance_id,
+                cfg.name().c_str());
+  uint64_t config_hash = ComputeConfigHash(cfg);
+
+  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->config_hash == config_hash) {
+        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;
+    }
+
+    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::lock_guard<std::recursive_mutex> guard(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->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_hash = config_hash;
+      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.internal_instance_index = i;
+      internal_state->data_source->OnSetup(setup_args);
+      return;
+    }
+    PERFETTO_ELOG(
+        "Maximum number of data source instances exhausted. "
+        "Dropping data source %" PRIu64,
+        instance_id);
+    break;
+  }
+}
+
+// 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;
+  }
+
+  DataSourceBase::StartArgs start_args{};
+  start_args.internal_instance_index = ds.instance_idx;
+
+  std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
+  if (ds.internal_state->interceptor)
+    ds.internal_state->interceptor->OnStart({});
+  ds.internal_state->trace_lambda_enabled = true;
+  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;
+  }
+
+  StopArgsImpl stop_args{};
+  stop_args.internal_instance_index = ds.instance_idx;
+  stop_args.async_stop_closure = [this, backend_id, instance_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, instance_id] {
+      StopDataSource_AsyncEnd(backend_id, instance_id);
+    });
+  };
+
+  {
+    std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
+    if (ds.internal_state->interceptor)
+      ds.internal_state->interceptor->OnStop({});
+    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,
+    DataSourceInstanceID instance_id) {
+  PERFETTO_DLOG("Ending async stop of data source %" PRIu64, instance_id);
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  auto ds = FindDataSource(backend_id, instance_id);
+  if (!ds) {
+    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.
+  {
+    std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
+    ds.internal_state->trace_lambda_enabled = false;
+    ds.internal_state->data_source.reset();
+  }
+
+  // The other fields of internal_state are deliberately *not* cleared.
+  // See races-related comments of DataSource::Trace().
+
+  TracingMuxer::generation_++;
+
+  // |backends_| is append-only, Backend instances are always valid.
+  PERFETTO_CHECK(backend_id < backends_.size());
+  ProducerImpl* producer = backends_[backend_id].producer.get();
+  if (!producer)
+    return;
+  if (producer->connected_) {
+    // Flush any commits that might have been batched by SharedMemoryArbiter.
+    producer->service_->MaybeSharedMemoryArbiter()
+        ->FlushPendingCommitDataRequests();
+    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;
+  }
+  // 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);
+}
+
+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 = backends_.size();
+      }
+      for (auto& backend : 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 : 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->backend_id == ds_tls.backend_id &&
+          ds_state->backend_connection_id == ds_tls.backend_connection_id &&
+          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_) {
+    for (RegisteredBackend& backend : backends_) {
+      // We cannot call RegisterDataSource on the backend before it connects.
+      if (!backend.producer->connected_)
+        continue;
+
+      PERFETTO_DCHECK(rds.static_state->index < kMaxDataSources);
+      if (backend.producer->registered_data_sources_.test(
+              rds.static_state->index))
+        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);
+      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;
+  }
+
+  consumer->service_->Flush(timeout_ms, std::move(callback));
+}
+
+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 (RegisteredBackend& backend : 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 (RegisteredBackend& backend : 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 (RegisteredBackend& backend : 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_);
+  for (RegisteredBackend& backend : backends_) {
+    for (auto& consumer : backend.consumers) {
+      if (consumer->session_id_ == session_id) {
+        return consumer.get();
+      }
+    }
+  }
+  return nullptr;
+}
+
+void TracingMuxerImpl::InitializeConsumer(TracingSessionGlobalID session_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  auto* consumer = FindConsumer(session_id);
+  if (!consumer)
+    return;
+
+  TracingBackendId backend_id = consumer->backend_id_;
+  // |backends_| is append-only, Backend instances are always valid.
+  PERFETTO_CHECK(backend_id < backends_.size());
+  RegisteredBackend& backend = backends_[backend_id];
+
+  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 (RegisteredBackend& backend : 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 (RegisteredBackend& backend : backends_) {
+    if (backend.producer.get() != producer)
+      continue;
+    // Try reconnecting the disconnected producer. If the connection succeeds,
+    // all the data sources will be automatically re-registered.
+    if (producer->connection_id_ > 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));
+  }
+
+  // Increment the generation counter to atomically ensure that:
+  // 1. Old trace writers from the severed connection eventually get cleaned up
+  //    by DestroyStoppedTraceWritersForCurrentThread().
+  // 2. No new trace writers can be created for the SharedMemoryArbiter from the
+  //    old connection.
+  TracingMuxer::generation_++;
+}
+
+TracingMuxerImpl::FindDataSourceRes TracingMuxerImpl::FindDataSource(
+    TracingBackendId backend_id,
+    DataSourceInstanceID instance_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  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->data_source_instance_id == instance_id) {
+        return FindDataSourceRes(static_state, internal_state, i);
+      }
+    }
+  }
+  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 = backends_[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_);
+  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) {
+  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] {
+    for (RegisteredBackend& backend : backends_) {
+      if (requested_backend_type && backend.type &&
+          backend.type != requested_backend_type) {
+        continue;
+      }
+
+      TracingBackendId backend_id = backend.id;
+
+      // 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, backend.id, session_id));
+
+      // The last registered backend in |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;
+      }
+
+      TracingPolicy::ShouldAllowConsumerSessionArgs args;
+      args.backend_type = backend.type;
+      args.result_callback = [this, backend_id, session_id](bool allow) {
+        task_runner_->PostTask([this, backend_id, session_id, allow] {
+          if (allow) {
+            InitializeConsumer(session_id);
+            return;
+          }
+
+          PERFETTO_ELOG(
+              "Consumer session for backend type type=%d forbidden, "
+              "consumer will disconnect",
+              backends_[backend_id].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));
+}
+
+void TracingMuxerImpl::InitializeInstance(const TracingInitArgs& args) {
+  if (instance_ != TracingMuxerFake::Get())
+    PERFETTO_FATAL("Tracing already initialized");
+  new TracingMuxerImpl(args);
+}
+
+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
+// 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 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 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 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);
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNED_FIELDS_H_
+// 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,
+  };
+
+  using FieldMetadata_AvailableCategories =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrackEventCategory,
+      TrackEventDescriptor>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AvailableCategories kAvailableCategories() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEventCategory>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Description kDescription() { return {}; }
+  void set_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Description::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tags kTags() { return {}; }
+  void add_tags(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tags::kFieldId, data, 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.
+/*
+ * 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/thread_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/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"
+
+namespace perfetto {
+
+TrackEventSessionObserver::~TrackEventSessionObserver() = default;
+void TrackEventSessionObserver::OnSetup(const DataSourceBase::SetupArgs&) {}
+void TrackEventSessionObserver::OnStart(const DataSourceBase::StartArgs&) {}
+void TrackEventSessionObserver::OnStop(const DataSourceBase::StopArgs&) {}
+
+namespace internal {
+
+BaseTrackEventInternedDataIndex::~BaseTrackEventInternedDataIndex() = default;
+
+namespace {
+
+std::atomic<perfetto::base::PlatformThreadId> g_main_thread;
+static constexpr const char kLegacySlowPrefix[] = "disabled-by-default-";
+static constexpr const char kSlowTag[] = "slow";
+static constexpr const char kDebugTag[] = "debug";
+
+void ForEachObserver(
+    std::function<bool(TrackEventSessionObserver*&)> callback) {
+  // Session observers, shared by all track event data source instances.
+  static constexpr int kMaxObservers = 8;
+  static std::recursive_mutex* mutex = new std::recursive_mutex{};  // Leaked.
+  static std::array<TrackEventSessionObserver*, kMaxObservers> observers{};
+  std::unique_lock<std::recursive_mutex> lock(*mutex);
+  for (auto& o : observers) {
+    if (!callback(o))
+      break;
+  }
+}
+
+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&)) {
+  if (!g_main_thread)
+    g_main_thread = perfetto::base::GetThreadId();
+
+  DataSourceDescriptor dsd;
+  dsd.set_name("track_event");
+
+  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(
+    TrackEventSessionObserver* observer) {
+  bool result = false;
+  ForEachObserver([&](TrackEventSessionObserver*& o) {
+    if (!o) {
+      o = observer;
+      result = true;
+      return false;
+    }
+    return true;
+  });
+  return result;
+}
+
+// static
+void TrackEventInternal::RemoveSessionObserver(
+    TrackEventSessionObserver* observer) {
+  ForEachObserver([&](TrackEventSessionObserver*& o) {
+    if (o == observer) {
+      o = nullptr;
+      return false;
+    }
+    return true;
+  });
+}
+
+// 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);
+  }
+  ForEachObserver([&](TrackEventSessionObserver*& o) {
+    if (o)
+      o->OnSetup(args);
+    return true;
+  });
+}
+
+// static
+void TrackEventInternal::OnStart(const DataSourceBase::StartArgs& args) {
+  session_count_.fetch_add(1);
+  ForEachObserver([&](TrackEventSessionObserver*& o) {
+    if (o)
+      o->OnStart(args);
+    return true;
+  });
+}
+
+// static
+void TrackEventInternal::DisableTracing(
+    const TrackEventCategoryRegistry& registry,
+    const DataSourceBase::StopArgs& args) {
+  ForEachObserver([&](TrackEventSessionObserver*& o) {
+    if (o)
+      o->OnStop(args);
+    return true;
+  });
+  for (size_t i = 0; i < registry.category_count(); i++)
+    registry.DisableCategoryForInstance(i, args.internal_instance_index);
+}
+
+// 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;
+    }
+
+    // 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());
+  PERFETTO_DCHECK(GetClockId() == protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
+  return static_cast<uint64_t>(perfetto::base::GetWallTimeNs().count());
+}
+
+// static
+int TrackEventInternal::GetSessionCount() {
+  return session_count_.load();
+}
+
+// static
+void TrackEventInternal::ResetIncrementalState(TraceWriterBase* trace_writer,
+                                               TraceTimestamp timestamp) {
+  auto default_track = ThreadTrack::Current();
+  {
+    // 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, timestamp,
+        protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED);
+    auto defaults = packet->set_trace_packet_defaults();
+    defaults->set_timestamp_clock_id(GetClockId());
+
+    // Establish the default track for this event sequence.
+    auto track_defaults = defaults->set_track_event_defaults();
+    track_defaults->set_track_uuid(default_track.uuid);
+  }
+
+  // Every thread should write a descriptor for its default track, because most
+  // trace points won't explicitly reference it.
+  WriteTrackDescriptor(default_track, trace_writer);
+
+  // Additionally the main thread should dump the process descriptor.
+  if (perfetto::base::GetThreadId() == g_main_thread)
+    WriteTrackDescriptor(ProcessTrack::Current(), trace_writer);
+}
+
+// static
+protozero::MessageHandle<protos::pbzero::TracePacket>
+TrackEventInternal::NewTracePacket(TraceWriterBase* trace_writer,
+                                   TraceTimestamp timestamp,
+                                   uint32_t seq_flags) {
+  auto packet = trace_writer->NewTracePacket();
+  packet->set_timestamp(timestamp.nanoseconds);
+  if (timestamp.clock_id != GetClockId()) {
+    packet->set_timestamp_clock_id(static_cast<uint32_t>(timestamp.clock_id));
+  } else if (GetClockId() != protos::pbzero::BUILTIN_CLOCK_BOOTTIME) {
+    // TODO(skyostil): Stop emitting the clock id for the default trace clock
+    // for every event once the trace processor understands trace packet
+    // defaults.
+    packet->set_timestamp_clock_id(GetClockId());
+  }
+  packet->set_sequence_flags(seq_flags);
+  return packet;
+}
+
+// static
+EventContext TrackEventInternal::WriteEvent(
+    TraceWriterBase* trace_writer,
+    TrackEventIncrementalState* incr_state,
+    const Category* category,
+    const char* name,
+    perfetto::protos::pbzero::TrackEvent::Type type,
+    TraceTimestamp timestamp) {
+  PERFETTO_DCHECK(g_main_thread);
+  PERFETTO_DCHECK(!incr_state->was_cleared);
+
+  auto packet = NewTracePacket(trace_writer, timestamp);
+  EventContext ctx(std::move(packet), incr_state);
+
+  auto track_event = ctx.event();
+  if (type != protos::pbzero::TrackEvent::TYPE_UNSPECIFIED)
+    track_event->set_type(type);
+
+  // We assume that |category| and |name| point to strings 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;
+        });
+  }
+  if (name && type != protos::pbzero::TrackEvent::TYPE_SLICE_END) {
+    size_t name_iid = InternedEventName::Get(&ctx, name);
+    track_event->set_name_iid(name_iid);
+  }
+  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;
+}
+
+}  // 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);
+}
+
+}  // 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;
+
+// static
+std::unique_ptr<PlatformThreadLocalObject>
+PlatformThreadLocalObject::CreateInstance() {
+  return std::unique_ptr<PlatformThreadLocalObject>(new internal::TracingTLS());
+}
+
+}  // 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 "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
+
+namespace perfetto {
+
+namespace internal {
+
+TracedValue CreateTracedValueFromProto(
+    protos::pbzero::DebugAnnotation* context) {
+  return TracedValue::CreateFromProto(context);
+}
+
+}  // namespace internal
+
+// static
+TracedValue TracedValue::CreateFromProto(
+    protos::pbzero::DebugAnnotation* context) {
+  return TracedValue(context, nullptr);
+}
+
+void TracedValue::WriteInt64(int64_t value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  context_->set_int_value(value);
+}
+
+void TracedValue::WriteUInt64(uint64_t value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  context_->set_uint_value(value);
+}
+
+void TracedValue::WriteDouble(double value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  context_->set_double_value(value);
+}
+
+void TracedValue::WriteBoolean(bool value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  context_->set_bool_value(value);
+}
+
+void TracedValue::WriteString(const char* value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  context_->set_string_value(value);
+}
+
+void TracedValue::WriteString(const char* value, size_t len) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  context_->set_string_value(value, len);
+}
+
+void TracedValue::WriteString(const std::string& value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  context_->set_string_value(value);
+}
+
+void TracedValue::WritePointer(const void* value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  context_->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(!context_->is_finalized());
+  return TracedDictionary(context_,
+                          protos::pbzero::DebugAnnotation::kDictEntries,
+                          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(!context_->is_finalized());
+  return TracedArray(context_, checked_scope_.parent_scope());
+}
+
+TracedValue TracedArray::AppendItem() {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  return TracedValue(context_->add_array_values(), &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();
+}
+
+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, &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, &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
+/*
+ * 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/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;
+}
+
+// static
+void Tracing::InitializeInternal(const TracingInitArgs& args) {
+  static TracingInitArgs init_args;
+  if (g_was_initialized) {
+    if (!(init_args == args)) {
+      PERFETTO_ELOG(
+          "Tracing::Initialize() called more than once with different args. "
+          "This is not supported, only the first call will have effect.");
+      PERFETTO_DCHECK(false);
+    }
+    return;
+  }
+
+  // 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) {
+    SetLogMessageCallback(args.log_message_callback);
+  }
+  internal::TracingMuxerImpl::InitializeInstance(args);
+  internal::TrackRegistry::InitializeInstance();
+  g_was_initialized = true;
+  init_args = args;
+}
+
+// static
+bool Tracing::IsInitialized() {
+  return g_was_initialized;
+}
+
+//  static
+std::unique_ptr<TracingSession> Tracing::NewTrace(BackendType backend) {
+  return static_cast<internal::TracingMuxerImpl*>(internal::TracingMuxer::Get())
+      ->CreateTracingSession(backend);
+}
+
+// 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;
+}
+
+}  // 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 "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));
+  std::string thread_name;
+  if (base::GetThreadName(thread_name))
+    td->set_thread_name(thread_name);
+  return desc;
+}
+
+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 (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() {
+  // TODO(eseckler): Chrome may call this more than once. Once Chrome doesn't
+  // call this directly anymore, bring back DCHECK(!instance_) instead.
+  if (instance_)
+    return;
+  instance_ = new TrackRegistry();
+
+  // 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::Hash hash;
+    hash.Update(start_time);
+    hash.Update(base::GetProcessId());
+    Track::process_uuid = hash.digest();
+  } else {
+    // Fall back to a randomly generated identifier.
+    Track::process_uuid = static_cast<uint64_t>(base::Uuidv4().lsb());
+  }
+}
+
+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/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);
+  switch (scope_flags) {
+    case legacy::kTraceEventFlagHasId:
+      event->set_unscoped_id(raw_id_);
+      break;
+    case legacy::kTraceEventFlagHasLocalId:
+      event->set_local_id(raw_id_);
+      break;
+    case legacy::kTraceEventFlagHasGlobalId:
+      event->set_global_id(raw_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 "protos/perfetto/common/interceptor_descriptor.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/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 {
+
+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());
+
+  // TODO(skyostil): Support incremental timestamps.
+  uint64_t timestamp = packet.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::Hash 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
+
+  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 (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
+
+TracingBackend::~TracingBackend() = default;
+TracingSession::~TracingSession() = 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,
+
+  // 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,
+
+  // Checkpoints inside perfetto_cmd after tracing has finished.
+  kOnTracingDisabled = 4,
+  kUploadIncidentBegin = 8,
+  kFinalizeTraceAndExit = 11,
+  kNotUploadingEmptyTrace = 17,
+
+  // Guardrails inside perfetto_cmd after tracing has finished.
+  kUploadIncidentFailure = 10,
+
+  // Deprecated as "success" is misleading; it simply means we were
+  // able to communicate with incidentd. Will be removed once
+  // incidentd is properly instrumented.
+  kUploadIncidentSuccess = 9,
+
+  // Deprecated as has the potential to be too spammy. Will be
+  // replaced with a whole new atom proto which uses a count metric
+  // instead of the event metric used for this proto.
+  kTriggerBegin = 12,
+  kTriggerSuccess = 13,
+  kTriggerFailure = 14,
+
+  // Deprecated as too coarse grained to be useful. Will be replaced
+  // with better broken down atoms as we do with traced.
+  kHitGuardrails = 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/base/cmds/statsd/src/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/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 <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 && simple_field()==false, 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) or a nested field that needs recursion.
+    // In the latter case the caller is expected to use |nested_msg_index| for
+    // the next Query() calls.
+    bool simple_field() const { return nested_msg_index == kSimpleField; }
+  };
+
+  // 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);
+
+  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;
+
+  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: 0 if the field is disallowed, 1 if allowed.
+  //         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.
+  //  [0, 7ffffffe]: 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
+  //     filter bytecode, has no proto-equivalent match (unlike field ids).
+  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,
+};
+}  // 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::Hash 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);
+  };
+
+  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;
+
+    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) {
+      // 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..f in the case of simple messages.
+      uint32_t msg_id;
+      if (opcode == kFilterOpcode_SimpleField) {
+        msg_id = kSimpleField;
+      } 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 (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) {
+  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.simple_field() ||
+                  res.nested_msg_index < message_offset_.size() - 1);
+  return res;
+}
+
+}  // 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"
+
+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:
+  MessageFilter();
+  ~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);
+
+  // 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(const uint32_t* field_ids, size_t num_fields);
+
+  // 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_;
+  }
+
+  // Exposed only for DCHECKS in TracingServiceImpl.
+  uint32_t root_msg_index() { return root_msg_index_; }
+
+ 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;
+
+    // When true the next |eat_next_bytes| are copied as-is in output.
+    // 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).
+    bool passthrough_eaten_bytes = false;
+  };
+
+  uint32_t out_written() { return static_cast<uint32_t>(out_ - &out_buf_[0]); }
+
+  std::unique_ptr<uint8_t[]> out_buf_;
+  uint8_t* out_ = nullptr;
+  uint8_t* out_end_ = nullptr;
+  uint32_t root_msg_index_ = 0;
+
+  FilterBytecodeParser filter_;
+  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"
+
+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() {
+  // Push a state on the stack for the implicit root message.
+  stack_.emplace_back();
+}
+
+MessageFilter::~MessageFilter() = default;
+
+bool MessageFilter::LoadFilterBytecode(const void* filter_data, size_t len) {
+  return filter_.Load(filter_data, len);
+}
+
+bool MessageFilter::SetFilterRoot(const uint32_t* field_ids,
+                                  size_t num_fields) {
+  uint32_t root_msg_idx = 0;
+  for (const uint32_t* it = field_ids; it < field_ids + num_fields; ++it) {
+    uint32_t field_id = *it;
+    auto res = filter_.Query(root_msg_idx, field_id);
+    if (!res.allowed || res.simple_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 = 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 in output
+    // if the field was allowed.
+    --state->eat_next_bytes;
+    if (state->passthrough_eaten_bytes)
+      *(out_++) = octet;
+  } 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 = 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.simple_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;
+            state->passthrough_eaten_bytes = filter.allowed;
+            if (filter.allowed)
+              AppendLenDelim(token.field_id, submessage_len, &out_);
+          }
+          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.passthrough_eaten_bytes = false;
+  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_
+// 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_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*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_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(); }
+  uint32_t event_duration_ns() const { return at<3>().as_uint32(); }
+  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); }
+};
+
+class PerfettoMetatrace : public ::protozero::Message {
+ public:
+  using Decoder = PerfettoMetatrace_Decoder;
+  enum : int32_t {
+    kEventIdFieldNumber = 1,
+    kCounterIdFieldNumber = 2,
+    kEventNameFieldNumber = 8,
+    kCounterNameFieldNumber = 9,
+    kEventDurationNsFieldNumber = 3,
+    kCounterValueFieldNumber = 4,
+    kThreadIdFieldNumber = 5,
+    kHasOverrunsFieldNumber = 6,
+    kArgsFieldNumber = 7,
+  };
+  using Arg = ::perfetto::protos::pbzero::PerfettoMetatrace_Arg;
+
+  using FieldMetadata_EventId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfettoMetatrace>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EventId kEventId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CounterId kCounterId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EventName kEventName() { return {}; }
+  void set_event_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EventName::kFieldId, data, 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_CounterName =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfettoMetatrace>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CounterName kCounterName() { return {}; }
+  void set_counter_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_CounterName::kFieldId, data, 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::kUint32,
+      uint32_t,
+      PerfettoMetatrace>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EventDurationNs kEventDurationNs() { return {}; }
+  void set_event_duration_ns(uint32_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::kUint32>
+        ::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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CounterValue kCounterValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadId kThreadId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HasOverruns kHasOverruns() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Args kArgs() { return {}; }
+  template <typename T = PerfettoMetatrace_Arg> T* add_args() {
+    return BeginNestedMessage<T>(7);
+  }
+
+};
+
+class PerfettoMetatrace_Arg_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*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_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class PerfettoMetatrace_Arg : public ::protozero::Message {
+ public:
+  using Decoder = PerfettoMetatrace_Arg_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfettoMetatrace_Arg>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Key kKey() { return {}; }
+  void set_key(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Key::kFieldId, data, 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,
+      PerfettoMetatrace_Arg>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Value kValue() { return {}; }
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, 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.
+/*
+ * 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 {
+
+// static
+constexpr char MetatraceWriter::kDataSourceName[];
+
+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,
+};
+
+// 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
+/*
+ * 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/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/slice.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.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;
+    uid_t producer_uid_trusted;
+    WriterID writer_id;
+  };
+
+  // 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,
+                          uid_t producer_uid_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);
+
+  const TraceStats::BufferStats& stats() const { return stats_; }
+  size_t size() const { return size_; }
+
+ 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.
+    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} {}
+
+      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(ChunkRecord* r, uint16_t p, bool complete, uint8_t f, uid_t u)
+        : chunk_record{r}, trusted_uid{u}, flags{f}, num_fragments{p} {
+      if (complete)
+        index_flags = kComplete;
+    }
+
+    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;
+      }
+    }
+
+    ChunkRecord* const chunk_record;  // Addr of ChunkRecord within |data_|.
+    const uid_t trusted_uid;          // uid of the producer.
+
+    // 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;
+
+  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(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.
+    data_.EnsureCommitted(
+        static_cast<size_t>(ptr + sizeof(ChunkRecord) - begin()));
+    return reinterpret_cast<ChunkRecord*>(ptr);
+  }
+
+  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));
+    PERFETTO_CHECK(record.size <= size_to_end());
+    DcheckIsAlignedAndWithinBounds(wptr);
+
+    // We may be writing to this area for the first time.
+    data_.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);
+  }
+
+  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_|.
+  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;
+
+  // 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_;
+
+#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/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
+namespace {
+constexpr char kHexDigits[] = "0123456789abcdef";
+std::string HexDump(const uint8_t* src, size_t size) {
+  std::string buf;
+  buf.reserve(4096 * 4);
+  char line[64];
+  char* c = line;
+  for (size_t i = 0; i < size; i++) {
+    *c++ = kHexDigits[(src[i] >> 4) & 0x0f];
+    *c++ = kHexDigits[(src[i] >> 0) & 0x0f];
+    if (i % 16 == 15) {
+      buf.append("\n");
+      buf.append(line);
+      c = line;
+    }
+  }
+  return buf;
+}
+}  // namespace
+#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.
+
+constexpr size_t TraceBuffer::ChunkRecord::kMaxSize;
+constexpr 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");
+  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;
+  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,
+                                     uid_t producer_uid_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) {
+  // |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));
+  if (PERFETTO_UNLIKELY(record_size > max_chunk_size_)) {
+    stats_.set_abi_violations(stats_.abi_violations() + 1);
+    PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
+    return;
+  }
+
+  TRACE_BUFFER_DLOG("CopyChunk @ %lu, size=%zu", wptr_ - begin(), record_size);
+
+#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;
+  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 = record_meta->chunk_record;
+
+    // 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 @ %lu, 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 @ [%lu - %lu] %zu", wptr - begin(),
+                      uintptr_t(wptr - begin()) + record_size, record_size);
+    WriteChunkRecord(wptr, record, src, size);
+    TRACE_BUFFER_DLOG("Chunk raw: %s", 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);
+  auto it_and_inserted = index_.emplace(
+      key, ChunkMeta(GetChunkRecordAt(wptr_), num_fragments, chunk_complete,
+                     chunk_flags, producer_uid_trusted));
+  PERFETTO_DCHECK(it_and_inserted.second);
+  TRACE_BUFFER_DLOG("  copying @ [%lu - %lu] %zu", wptr_ - begin(),
+                    uintptr_t(wptr_ - begin()) + record_size, record_size);
+  WriteChunkRecord(wptr_, record, src, size);
+  TRACE_BUFFER_DLOG("Chunk raw: %s", 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} @ [%lu - %lu] %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 @ [%lu - %lu] %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) {
+  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.
+  PERFETTO_DCHECK(ChunkMeta::Key(*chunk_meta.chunk_record) == key);
+  uint8_t* chunk_begin = reinterpret_cast<uint8_t*>(chunk_meta.chunk_record);
+  PERFETTO_DCHECK(chunk_begin >= begin());
+  uint8_t* chunk_end = chunk_begin + chunk_meta.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;
+    }
+
+    // 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.
+    char zero[Patch::kSize]{};
+    PERFETTO_DCHECK(memcmp(ptr, &zero, Patch::kSize) == 0);
+
+    memcpy(ptr, &patches[i].data[0], Patch::kSize);
+  }
+  TRACE_BUFFER_DLOG(
+      "Chunk raw (after patch): %s",
+      HexDump(chunk_begin, chunk_meta.chunk_record->size).c_str());
+
+  stats_.set_patches_succeeded(stats_.patches_succeeded() + patches_size);
+  if (!other_patches_pending) {
+    chunk_meta.flags &= ~kChunkNeedsPatching;
+    chunk_meta.chunk_record->flags = chunk_meta.flags;
+  }
+  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, kInvalidUid, 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 uid_t trusted_uid = chunk_meta->trusted_uid;
+
+    // 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(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(chunk_meta, packet);
+
+        if (PERFETTO_LIKELY(result == ReadPacketResult::kSucceeded)) {
+          *sequence_properties = {trusted_producer_id, trusted_uid, 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, trusted_uid, 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.
+        packet_corruption |= ReadNextPacketInChunk(&*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(
+    ChunkMeta* 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 =
+      reinterpret_cast<const uint8_t*>(chunk_meta->chunk_record);
+  const uint8_t* record_end = record_begin + chunk_meta->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_meta->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_meta->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_meta->chunk_record->size);
+  } 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_meta->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");
+}
+
+}  // 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 <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
+  };
+
+  CircularQueue(size_t initial_capacity = 1024) { Grow(initial_capacity); }
+
+  CircularQueue(CircularQueue&& other) noexcept {
+    // Copy all fields using the (private) default copy assignment operator.
+    *this = other;
+    increment_generation();
+    new (&other) CircularQueue();  // Reset the old queue so it's still usable.
+  }
+
+  CircularQueue& operator=(CircularQueue&& other) {
+    this->~CircularQueue();                      // Destroy the current state.
+    new (this) CircularQueue(std::move(other));  // Use the move ctor above.
+    return *this;
+  }
+
+  ~CircularQueue() {
+    if (!entries_) {
+      PERFETTO_DCHECK(empty());
+      return;
+    }
+    clear();  // Invoke destructors on all alive entries.
+    PERFETTO_DCHECK(empty());
+    free(entries_);
+  }
+
+  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()); }
+
+  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:
+  CircularQueue(const CircularQueue&) = delete;
+  CircularQueue& operator=(const CircularQueue&) = default;
+
+  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_);
+    size_t malloc_size = new_capacity * sizeof(T);
+    PERFETTO_CHECK(malloc_size > new_capacity);
+    auto* new_vec = static_cast<T*>(malloc(malloc_size));
+
+    // 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();
+    free(entries_);  // It's fine to free(nullptr) (for the ctor call case).
+
+    begin_ = 0;
+    end_ = new_size;
+    capacity_ = new_capacity;
+    entries_ = 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.
+  T* entries_ = nullptr;
+  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 <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/optional.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/periodic_task.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/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
+
+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 kDefaultShmPageSize = 4096ul;
+  static constexpr size_t kDefaultShmSize = 256 * 1024ul;
+  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};
+
+  // The implementation behind the service endpoint exposed to each producer.
+  class ProducerEndpointImpl : public TracingService::ProducerEndpoint {
+   public:
+    ProducerEndpointImpl(ProducerID,
+                         uid_t uid,
+                         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 RegisterDataSource(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>&);
+    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);
+    }
+
+    base::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 base::nullopt;
+    }
+
+    uid_t uid() const { return uid_; }
+
+   private:
+    friend class TracingServiceImpl;
+    friend class TracingServiceImplTest;
+    friend class TracingIntegrationTest;
+    ProducerEndpointImpl(const ProducerEndpointImpl&) = delete;
+    ProducerEndpointImpl& operator=(const ProducerEndpointImpl&) = delete;
+
+    ProducerID const id_;
+    const uid_t uid_;
+    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);
+
+    // 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) 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;
+
+    // Will queue a task to notify the consumer about the state change.
+    void OnDataSourceInstanceStateChange(const ProducerEndpointImpl&,
+                                         const DataSourceInstance&);
+    void OnAllDataSourcesStarted();
+
+   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*);
+  ~TracingServiceImpl() override;
+
+  // Called by ProducerEndpointImpl.
+  void DisconnectProducer(ProducerID);
+  void RegisterDataSource(ProducerID, const DataSourceDescriptor&);
+  void UnregisterDataSource(ProducerID, const std::string& name);
+  void CopyProducerPageIntoLogBuffer(ProducerID,
+                                     uid_t,
+                                     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);
+  void FlushAndDisableTracing(TracingSessionID);
+  bool ReadBuffers(TracingSessionID, ConsumerEndpointImpl*);
+  void FreeBuffers(TracingSessionID);
+
+  // Service implementation.
+  std::unique_ptr<TracingService::ProducerEndpoint> ConnectProducer(
+      Producer*,
+      uid_t uid,
+      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)
+        : 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) {}
+    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;
+
+    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
+    };
+
+    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(ProducerID producer_id,
+                                         WriterID writer_id) {
+      auto key = std::make_pair(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.
+    // TODO(rsavitski): at the time of writing, the map structure is unused
+    // (even when the calling code has a key). This is also an opportunity to
+    // consider an alternative data type, e.g. a map of vectors.
+    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::pair<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 mirrored the trace config back to the trace output yet.
+    bool did_emit_config = false;
+
+    // Whether we put the system info into the trace output yet.
+    bool did_emit_system_info = 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;
+
+    // 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;
+
+    // Set when using SaveTraceForBugreport(). This callback will be called
+    // when the tracing session ends and the data has been saved into the file.
+    std::function<void()> on_disable_callback_for_bugreport;
+    bool seized_for_bugreport = false;
+
+    // Periodic task for snapshotting service events (e.g. clocks, sync markers
+    // etc)
+    base::PeriodicTask snapshot_periodic_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;
+  };
+
+  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_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 EmitSeizedForBugreportLifecycleEvent(std::vector<TracePacket>*);
+  void MaybeEmitTraceConfig(TracingSession*, std::vector<TracePacket>*);
+  void MaybeEmitSystemInfo(TracingSession*, std::vector<TracePacket>*);
+  void MaybeEmitReceivedTriggers(TracingSession*, std::vector<TracePacket>*);
+  void MaybeNotifyAllDataSourcesStarted(TracingSession*);
+  bool MaybeSaveTraceForBugreport(std::function<void()> callback);
+  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);
+  void OnStartTriggersTimeout(TracingSessionID tsid);
+  void MaybeLogUploadEvent(const TraceConfig&,
+                           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);
+
+  base::TaskRunner* const task_runner_;
+  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_
+// 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_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*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_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(); }
+};
+
+class TraceStats : public ::protozero::Message {
+ public:
+  using Decoder = TraceStats_Decoder;
+  enum : int32_t {
+    kBufferStatsFieldNumber = 1,
+    kProducersConnectedFieldNumber = 2,
+    kProducersSeenFieldNumber = 3,
+    kDataSourcesRegisteredFieldNumber = 4,
+    kDataSourcesSeenFieldNumber = 5,
+    kTracingSessionsFieldNumber = 6,
+    kTotalBuffersFieldNumber = 7,
+    kChunksDiscardedFieldNumber = 8,
+    kPatchesDiscardedFieldNumber = 9,
+    kInvalidPacketsFieldNumber = 10,
+    kFilterStatsFieldNumber = 11,
+  };
+  using BufferStats = ::perfetto::protos::pbzero::TraceStats_BufferStats;
+  using FilterStats = ::perfetto::protos::pbzero::TraceStats_FilterStats;
+
+  using FieldMetadata_BufferStats =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceStats_BufferStats,
+      TraceStats>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BufferStats kBufferStats() { return {}; }
+  template <typename T = TraceStats_BufferStats> T* add_buffer_stats() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ProducersConnected =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceStats>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProducersConnected kProducersConnected() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProducersSeen kProducersSeen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DataSourcesRegistered kDataSourcesRegistered() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DataSourcesSeen kDataSourcesSeen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TracingSessions kTracingSessions() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TotalBuffers kTotalBuffers() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChunksDiscarded kChunksDiscarded() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PatchesDiscarded kPatchesDiscarded() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InvalidPackets kInvalidPackets() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FilterStats kFilterStats() { return {}; }
+  template <typename T = TraceStats_FilterStats> T* set_filter_stats() {
+    return BeginNestedMessage<T>(11);
+  }
+
+};
+
+class TraceStats_FilterStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ 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(); }
+};
+
+class TraceStats_FilterStats : public ::protozero::Message {
+ public:
+  using Decoder = TraceStats_FilterStats_Decoder;
+  enum : int32_t {
+    kInputPacketsFieldNumber = 1,
+    kInputBytesFieldNumber = 2,
+    kOutputBytesFieldNumber = 3,
+    kErrorsFieldNumber = 4,
+  };
+
+  using FieldMetadata_InputPackets =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_FilterStats>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InputPackets kInputPackets() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InputBytes kInputBytes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OutputBytes kOutputBytes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Errors kErrors() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_BufferSize =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BufferSize kBufferSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BytesWritten kBytesWritten() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BytesOverwritten kBytesOverwritten() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BytesRead kBytesRead() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PaddingBytesWritten kPaddingBytesWritten() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PaddingBytesCleared kPaddingBytesCleared() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChunksWritten kChunksWritten() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChunksRewritten kChunksRewritten() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChunksOverwritten kChunksOverwritten() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChunksDiscarded kChunksDiscarded() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChunksRead kChunksRead() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChunksCommittedOutOfOrder kChunksCommittedOutOfOrder() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WriteWrapCount kWriteWrapCount() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PatchesSucceeded kPatchesSucceeded() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PatchesFailed kPatchesFailed() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReadaheadsSucceeded kReadaheadsSucceeded() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReadaheadsFailed kReadaheadsFailed() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AbiViolations kAbiViolations() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceWriterPacketLoss kTraceWriterPacketLoss() { return {}; }
+  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/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_BufferConfig;
+class TraceConfig_BuiltinDataSource;
+class TraceConfig_DataSource;
+class TraceConfig_GuardrailOverrides;
+class TraceConfig_IncidentReportConfig;
+class TraceConfig_IncrementalStateConfig;
+class TraceConfig_ProducerConfig;
+class TraceConfig_StatsdMetadata;
+class TraceConfig_TraceFilter;
+class TraceConfig_TriggerConfig;
+class TraceConfig_TriggerConfig_Trigger;
+enum BuiltinClock : int32_t;
+enum TraceConfig_BufferConfig_FillPolicy : int32_t;
+enum TraceConfig_CompressionType : int32_t;
+enum TraceConfig_LockdownModeOperation : int32_t;
+enum TraceConfig_StatsdLogging : int32_t;
+enum TraceConfig_TriggerConfig_TriggerMode : int32_t;
+
+enum TraceConfig_LockdownModeOperation : int32_t {
+  TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED = 0,
+  TraceConfig_LockdownModeOperation_LOCKDOWN_CLEAR = 1,
+  TraceConfig_LockdownModeOperation_LOCKDOWN_SET = 2,
+};
+
+const TraceConfig_LockdownModeOperation TraceConfig_LockdownModeOperation_MIN = TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED;
+const TraceConfig_LockdownModeOperation TraceConfig_LockdownModeOperation_MAX = TraceConfig_LockdownModeOperation_LOCKDOWN_SET;
+
+enum TraceConfig_CompressionType : int32_t {
+  TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED = 0,
+  TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE = 1,
+};
+
+const TraceConfig_CompressionType TraceConfig_CompressionType_MIN = TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED;
+const TraceConfig_CompressionType TraceConfig_CompressionType_MAX = TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE;
+
+enum TraceConfig_StatsdLogging : int32_t {
+  TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED = 0,
+  TraceConfig_StatsdLogging_STATSD_LOGGING_ENABLED = 1,
+  TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED = 2,
+};
+
+const TraceConfig_StatsdLogging TraceConfig_StatsdLogging_MIN = TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED;
+const TraceConfig_StatsdLogging TraceConfig_StatsdLogging_MAX = TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED;
+
+enum TraceConfig_TriggerConfig_TriggerMode : int32_t {
+  TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED = 0,
+  TraceConfig_TriggerConfig_TriggerMode_START_TRACING = 1,
+  TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING = 2,
+};
+
+const TraceConfig_TriggerConfig_TriggerMode TraceConfig_TriggerConfig_TriggerMode_MIN = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
+const TraceConfig_TriggerConfig_TriggerMode TraceConfig_TriggerConfig_TriggerMode_MAX = TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING;
+
+enum TraceConfig_BufferConfig_FillPolicy : int32_t {
+  TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED = 0,
+  TraceConfig_BufferConfig_FillPolicy_RING_BUFFER = 1,
+  TraceConfig_BufferConfig_FillPolicy_DISCARD = 2,
+};
+
+const TraceConfig_BufferConfig_FillPolicy TraceConfig_BufferConfig_FillPolicy_MIN = TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED;
+const TraceConfig_BufferConfig_FillPolicy TraceConfig_BufferConfig_FillPolicy_MAX = TraceConfig_BufferConfig_FillPolicy_DISCARD;
+
+class TraceConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/32, /*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_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_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<32>().valid(); }
+  ::protozero::ConstBytes trace_filter() const { return at<32>().as_bytes(); }
+};
+
+class TraceConfig : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_Decoder;
+  enum : int32_t {
+    kBuffersFieldNumber = 1,
+    kDataSourcesFieldNumber = 2,
+    kBuiltinDataSourcesFieldNumber = 20,
+    kDurationMsFieldNumber = 3,
+    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,
+    kIncidentReportConfigFieldNumber = 25,
+    kStatsdLoggingFieldNumber = 31,
+    kTraceUuidMsbFieldNumber = 27,
+    kTraceUuidLsbFieldNumber = 28,
+    kTraceFilterFieldNumber = 32,
+  };
+  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 LockdownModeOperation = ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation;
+  using CompressionType = ::perfetto::protos::pbzero::TraceConfig_CompressionType;
+  using StatsdLogging = ::perfetto::protos::pbzero::TraceConfig_StatsdLogging;
+  static const LockdownModeOperation LOCKDOWN_UNCHANGED = TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED;
+  static const LockdownModeOperation LOCKDOWN_CLEAR = TraceConfig_LockdownModeOperation_LOCKDOWN_CLEAR;
+  static const LockdownModeOperation LOCKDOWN_SET = TraceConfig_LockdownModeOperation_LOCKDOWN_SET;
+  static const CompressionType COMPRESSION_TYPE_UNSPECIFIED = TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED;
+  static const CompressionType COMPRESSION_TYPE_DEFLATE = TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE;
+  static const StatsdLogging STATSD_LOGGING_UNSPECIFIED = TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED;
+  static const StatsdLogging STATSD_LOGGING_ENABLED = TraceConfig_StatsdLogging_STATSD_LOGGING_ENABLED;
+  static const StatsdLogging STATSD_LOGGING_DISABLED = TraceConfig_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Buffers kBuffers() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DataSources kDataSources() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BuiltinDataSources kBuiltinDataSources() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DurationMs kDurationMs() { return {}; }
+  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_EnableExtraGuardrails =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EnableExtraGuardrails kEnableExtraGuardrails() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LockdownMode kLockdownMode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Producers kProducers() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StatsdMetadata kStatsdMetadata() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WriteIntoFile kWriteIntoFile() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OutputPath kOutputPath() { return {}; }
+  void set_output_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_OutputPath::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FileWritePeriodMs kFileWritePeriodMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MaxFileSizeBytes kMaxFileSizeBytes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GuardrailOverrides kGuardrailOverrides() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DeferredStart kDeferredStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FlushPeriodMs kFlushPeriodMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FlushTimeoutMs kFlushTimeoutMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DataSourceStopTimeoutMs kDataSourceStopTimeoutMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NotifyTraceur kNotifyTraceur() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BugreportScore kBugreportScore() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TriggerConfig kTriggerConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ActivateTriggers kActivateTriggers() { return {}; }
+  void add_activate_triggers(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ActivateTriggers::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IncrementalStateConfig kIncrementalStateConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllowUserBuildTracing kAllowUserBuildTracing() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UniqueSessionName kUniqueSessionName() { return {}; }
+  void set_unique_session_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_UniqueSessionName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CompressionType kCompressionType() { return {}; }
+  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_IncidentReportConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_IncidentReportConfig,
+      TraceConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IncidentReportConfig kIncidentReportConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StatsdLogging kStatsdLogging() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceUuidMsb kTraceUuidMsb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceUuidLsb kTraceUuidLsb() { return {}; }
+  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<
+      32,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_TraceFilter,
+      TraceConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceFilter kTraceFilter() { return {}; }
+  template <typename T = TraceConfig_TraceFilter> T* set_trace_filter() {
+    return BeginNestedMessage<T>(32);
+  }
+
+};
+
+class TraceConfig_TraceFilter_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*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(); }
+};
+
+class TraceConfig_TraceFilter : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_TraceFilter_Decoder;
+  enum : int32_t {
+    kBytecodeFieldNumber = 1,
+  };
+
+  using FieldMetadata_Bytecode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      TraceConfig_TraceFilter>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Bytecode kBytecode() { return {}; }
+  void set_bytecode(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Bytecode::kFieldId, data, 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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_DestinationPackage =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_IncidentReportConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DestinationPackage kDestinationPackage() { return {}; }
+  void set_destination_package(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DestinationPackage::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DestinationClass kDestinationClass() { return {}; }
+  void set_destination_class(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DestinationClass::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PrivacyLevel kPrivacyLevel() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SkipIncidentd kSkipIncidentd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SkipDropbox kSkipDropbox() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_ClearPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_IncrementalStateConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClearPeriodMs kClearPeriodMs() { return {}; }
+  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=*/3, /*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_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,
+    kTriggersFieldNumber = 2,
+    kTriggerTimeoutMsFieldNumber = 3,
+  };
+  using Trigger = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_Trigger;
+  using TriggerMode = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode;
+  static const TriggerMode UNSPECIFIED = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
+  static const TriggerMode START_TRACING = TraceConfig_TriggerConfig_TriggerMode_START_TRACING;
+  static const TriggerMode STOP_TRACING = TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING;
+
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TriggerMode kTriggerMode() { return {}; }
+  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_Triggers =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_TriggerConfig_Trigger,
+      TraceConfig_TriggerConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Triggers kTriggers() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TriggerTimeoutMs kTriggerTimeoutMs() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_TriggerConfig_Trigger>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProducerNameRegex kProducerNameRegex() { return {}; }
+  void set_producer_name_regex(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerNameRegex::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StopDelayMs kStopDelayMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MaxPer24H kMaxPer24H() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SkipProbability kSkipProbability() { return {}; }
+  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=*/1, /*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(); }
+};
+
+class TraceConfig_GuardrailOverrides : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_GuardrailOverrides_Decoder;
+  enum : int32_t {
+    kMaxUploadPerDayBytesFieldNumber = 1,
+  };
+
+  using FieldMetadata_MaxUploadPerDayBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceConfig_GuardrailOverrides>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MaxUploadPerDayBytes kMaxUploadPerDayBytes() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_TriggeringAlertId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TraceConfig_StatsdMetadata>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TriggeringAlertId kTriggeringAlertId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TriggeringConfigUid kTriggeringConfigUid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TriggeringConfigId kTriggeringConfigId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TriggeringSubscriptionId kTriggeringSubscriptionId() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_ProducerName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_ProducerConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProducerName kProducerName() { return {}; }
+  void set_producer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ShmSizeKb kShmSizeKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PageSizeKb kPageSizeKb() { return {}; }
+  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=*/7, /*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(); }
+};
+
+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,
+  };
+
+  using FieldMetadata_DisableClockSnapshotting =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_BuiltinDataSource>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DisableClockSnapshotting kDisableClockSnapshotting() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DisableTraceConfig kDisableTraceConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DisableSystemInfo kDisableSystemInfo() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DisableServiceEvents kDisableServiceEvents() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PrimaryTraceClock kPrimaryTraceClock() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SnapshotIntervalMs kSnapshotIntervalMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PreferSuspendClockForSnapshot kPreferSuspendClockForSnapshot() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_Config =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DataSourceConfig,
+      TraceConfig_DataSource>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Config kConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProducerNameFilter kProducerNameFilter() { return {}; }
+  void add_producer_name_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerNameFilter::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProducerNameRegexFilter kProducerNameRegexFilter() { return {}; }
+  void add_producer_name_regex_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerNameRegexFilter::kFieldId, data, 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=*/4, /*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(); }
+};
+
+class TraceConfig_BufferConfig : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_BufferConfig_Decoder;
+  enum : int32_t {
+    kSizeKbFieldNumber = 1,
+    kFillPolicyFieldNumber = 4,
+  };
+  using FillPolicy = ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy;
+  static const FillPolicy UNSPECIFIED = TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED;
+  static const FillPolicy RING_BUFFER = TraceConfig_BufferConfig_FillPolicy_RING_BUFFER;
+  static const FillPolicy DISCARD = TraceConfig_BufferConfig_FillPolicy_DISCARD;
+
+  using FieldMetadata_SizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_BufferConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SizeKb kSizeKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FillPolicy kFillPolicy() { return {}; }
+  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);
+  }
+};
+
+} // 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;
+
+enum ClockSnapshot_Clock_BuiltinClocks : int32_t {
+  ClockSnapshot_Clock_BuiltinClocks_UNKNOWN = 0,
+  ClockSnapshot_Clock_BuiltinClocks_REALTIME = 1,
+  ClockSnapshot_Clock_BuiltinClocks_REALTIME_COARSE = 2,
+  ClockSnapshot_Clock_BuiltinClocks_MONOTONIC = 3,
+  ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_COARSE = 4,
+  ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_RAW = 5,
+  ClockSnapshot_Clock_BuiltinClocks_BOOTTIME = 6,
+  ClockSnapshot_Clock_BuiltinClocks_BUILTIN_CLOCK_MAX_ID = 63,
+};
+
+const ClockSnapshot_Clock_BuiltinClocks ClockSnapshot_Clock_BuiltinClocks_MIN = ClockSnapshot_Clock_BuiltinClocks_UNKNOWN;
+const ClockSnapshot_Clock_BuiltinClocks ClockSnapshot_Clock_BuiltinClocks_MAX = ClockSnapshot_Clock_BuiltinClocks_BUILTIN_CLOCK_MAX_ID;
+
+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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Clocks kClocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PrimaryTraceClock kPrimaryTraceClock() { return {}; }
+  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,
+  };
+  using BuiltinClocks = ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks;
+  static const BuiltinClocks UNKNOWN = ClockSnapshot_Clock_BuiltinClocks_UNKNOWN;
+  static const BuiltinClocks REALTIME = ClockSnapshot_Clock_BuiltinClocks_REALTIME;
+  static const BuiltinClocks REALTIME_COARSE = ClockSnapshot_Clock_BuiltinClocks_REALTIME_COARSE;
+  static const BuiltinClocks MONOTONIC = ClockSnapshot_Clock_BuiltinClocks_MONOTONIC;
+  static const BuiltinClocks MONOTONIC_COARSE = ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_COARSE;
+  static const BuiltinClocks MONOTONIC_RAW = ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_RAW;
+  static const BuiltinClocks BOOTTIME = ClockSnapshot_Clock_BuiltinClocks_BOOTTIME;
+  static const BuiltinClocks BUILTIN_CLOCK_MAX_ID = ClockSnapshot_Clock_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClockId kClockId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Timestamp kTimestamp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IsIncremental kIsIncremental() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UnitMultiplierNs kUnitMultiplierNs() { return {}; }
+  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/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,
+  };
+
+  using FieldMetadata_TracingStarted =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TracingStarted kTracingStarted() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllDataSourcesStarted kAllDataSourcesStarted() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllDataSourcesFlushed kAllDataSourcesFlushed() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReadTracingBuffersCompleted kReadTracingBuffersCompleted() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TracingDisabled kTracingDisabled() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SeizedForBugreport kSeizedForBugreport() { return {}; }
+  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/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=*/4, /*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(); }
+};
+
+class SystemInfo : public ::protozero::Message {
+ public:
+  using Decoder = SystemInfo_Decoder;
+  enum : int32_t {
+    kUtsnameFieldNumber = 1,
+    kAndroidBuildFingerprintFieldNumber = 2,
+    kHzFieldNumber = 3,
+    kTracingServiceVersionFieldNumber = 4,
+  };
+
+  using FieldMetadata_Utsname =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Utsname,
+      SystemInfo>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Utsname kUtsname() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AndroidBuildFingerprint kAndroidBuildFingerprint() { return {}; }
+  void set_android_build_fingerprint(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_AndroidBuildFingerprint::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Hz kHz() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TracingServiceVersion kTracingServiceVersion() { return {}; }
+  void set_tracing_service_version(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TracingServiceVersion::kFieldId, data, 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 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,
+  };
+
+  using FieldMetadata_Sysname =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Utsname>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sysname kSysname() { return {}; }
+  void set_sysname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Sysname::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Version kVersion() { return {}; }
+  void set_version(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Version::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Release kRelease() { return {}; }
+  void set_release(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Release::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Machine kMachine() { return {}; }
+  void set_machine(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Machine::kFieldId, data, 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/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,
+  };
+
+  using FieldMetadata_TriggerName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Trigger>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TriggerName kTriggerName() { return {}; }
+  void set_trigger_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TriggerName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProducerName kProducerName() { return {}; }
+  void set_producer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrustedProducerUid kTrustedProducerUid() { return {}; }
+  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.
+/*
+ * 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"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+
+#include <cinttypes>
+#include <regex>
+#include <unordered_set>
+
+#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)
+#include <sys/system_properties.h>
+#if 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  // PERFETTO_ANDROID_BUILD
+#endif  // PERFETTO_OS_ANDROID
+
+#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/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/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/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/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 {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
+    PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+// These are the only SELinux approved dir for trace files that are created
+// directly by traced.
+const char* kTraceDirBasePath = "/data/misc/perfetto-traces/";
+const char* kAndroidProductionBugreportTracePath =
+    "/data/misc/perfetto-traces/bugreport/systrace.pftrace";
+#endif
+
+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:
+// 1. TraceConfig.write_into_file == true and output_path is not empty.
+// 2. Calling SaveTraceForBugreport(), from perfetto --save-for-bugreport.
+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").
+  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;
+}
+
+std::string GetBugreportTmpPath() {
+  return GetBugreportPath() + ".tmp";
+}
+
+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:
+      // For backward compatibility with older versions of perfetto_cmd.
+      return cfg.enable_extra_guardrails();
+  }
+  PERFETTO_FATAL("For GCC");
+}
+
+}  // namespace
+
+// These constants instead are defined in the header because are used by tests.
+constexpr size_t TracingServiceImpl::kDefaultShmSize;
+constexpr size_t TracingServiceImpl::kDefaultShmPageSize;
+
+constexpr size_t TracingServiceImpl::kMaxShmSize;
+constexpr uint32_t TracingServiceImpl::kDataSourceStopTimeoutMs;
+constexpr uint8_t TracingServiceImpl::kSyncMarker[];
+
+std::string GetBugreportPath() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
+    PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+  return kAndroidProductionBugreportTracePath;
+#else
+  // Only for tests, SaveTraceForBugreport is not used on other OSes.
+  return base::GetSysTempDir() + "/bugreport.pftrace";
+#endif
+}
+
+// static
+std::unique_ptr<TracingService> TracingService::CreateInstance(
+    std::unique_ptr<SharedMemory::Factory> shm_factory,
+    base::TaskRunner* task_runner) {
+  return std::unique_ptr<TracingService>(
+      new TracingServiceImpl(std::move(shm_factory), task_runner));
+}
+
+TracingServiceImpl::TracingServiceImpl(
+    std::unique_ptr<SharedMemory::Factory> shm_factory,
+    base::TaskRunner* task_runner)
+    : task_runner_(task_runner),
+      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,
+                                    uid_t uid,
+                                    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_);
+
+  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, uid, 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_);
+  PERFETTO_DLOG("Enabling tracing for consumer %p",
+                reinterpret_cast<void*>(consumer));
+  MaybeLogUploadEvent(cfg, 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, 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,
+                        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 = cfg.trigger_config().trigger_mode() !=
+                                  TraceConfig::TriggerConfig::UNSPECIFIED;
+  if (has_trigger_config && (cfg.trigger_config().trigger_timeout_ms() == 0 ||
+                             cfg.trigger_config().trigger_timeout_ms() >
+                                 kGuardrailsMaxTracingDurationMillis)) {
+    MaybeLogUploadEvent(
+        cfg, 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());
+  }
+
+  if (has_trigger_config && cfg.duration_ms() != 0) {
+    MaybeLogUploadEvent(
+        cfg, PerfettoStatsdAtom::kTracedEnableTracingDurationWithTrigger);
+    return PERFETTO_SVC_ERR(
+        "duration_ms was set, this must not be set for traces with triggers.");
+  }
+
+  if (cfg.trigger_config().trigger_mode() ==
+          TraceConfig::TriggerConfig::STOP_TRACING &&
+      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 ReadBuffers 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, PerfettoStatsdAtom::kTracedEnableTracingStopTracingWriteIntoFile);
+    return PERFETTO_SVC_ERR(
+        "Specifying trigger mode STOP_TRACING 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, 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, 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, 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();
+    }
+    if (buf_size_sum > kGuardrailsMaxTracingBufferSizeKb) {
+      MaybeLogUploadEvent(
+          cfg, PerfettoStatsdAtom::kTracedEnableTracingBufferSizeTooLarge);
+      return PERFETTO_SVC_ERR("Requested too large trace buffer (%" PRIu64
+                              "kB  > %" PRIu32 " kB)",
+                              buf_size_sum, kGuardrailsMaxTracingBufferSizeKb);
+    }
+  }
+
+  if (cfg.buffers_size() > kMaxBuffersPerConsumer) {
+    MaybeLogUploadEvent(cfg,
+                        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, 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.config.unique_session_name() == name) {
+        MaybeLogUploadEvent(
+            cfg, 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, 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, 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, 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();
+    const std::string& bytecode = filt.bytecode();
+    trace_filter.reset(new protozero::MessageFilter());
+    if (!trace_filter->LoadFilterBytecode(bytecode.data(), bytecode.size())) {
+      MaybeLogUploadEvent(
+          cfg, 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.
+    uint32_t packet_field_id = TracePacket::kPacketFieldNumber;
+    if (!trace_filter->SetFilterRoot(&packet_field_id, 1)) {
+      MaybeLogUploadEvent(
+          cfg, 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;
+
+  if (trace_filter)
+    tracing_session->trace_filter = std::move(trace_filter);
+
+  if (cfg.write_into_file()) {
+    if (!fd ^ !cfg.output_path().empty()) {
+      tracing_sessions_.erase(tsid);
+      MaybeLogUploadEvent(
+          tracing_session->config,
+          PerfettoStatsdAtom::kTracedEnableTracingInvalidFdOutputFile);
+      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,
+            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;
+  }
+
+  // Initialize the log buffers.
+  bool did_allocate_all_buffers = true;
+
+  // 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);
+    const size_t buf_size_bytes = buffer_cfg.size_kb() * 1024u;
+    total_buf_size_kb += buffer_cfg.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_bytes, 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;
+    }
+  }
+
+  UpdateMemoryGuardrail();
+
+  // This can happen if either:
+  // - All the kMaxTraceBufferID slots are taken.
+  // - OOM, or, more relistically, we exhausted virtual memory.
+  // In any case, free all the previously allocated buffers and abort.
+  // TODO(fmayer): add a test to cover this case, this is quite subtle.
+  if (!did_allocate_all_buffers) {
+    for (BufferID global_id : tracing_session->buffers_index) {
+      buffer_ids_.Free(global_id);
+      buffers_.erase(global_id);
+    }
+    tracing_sessions_.erase(tsid);
+    MaybeLogUploadEvent(tracing_session->config,
+                        PerfettoStatsdAtom::kTracedEnableTracingOom);
+    return PERFETTO_SVC_ERR(
+        "Failed to allocate tracing buffers: OOM or too many buffers");
+  }
+
+  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 (cfg.trigger_config().trigger_mode()) {
+    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:
+      // 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;
+  }
+
+  tracing_session->state = TracingSession::CONFIGURED;
+  PERFETTO_LOG(
+      "Configured tracing session %" PRIu64
+      ", #sources:%zu, duration:%d ms, #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(),
+      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;
+
+    // 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;
+      }
+
+      bool already_setup = false;
+      auto& ds_instances = tracing_session->data_source_instances;
+      for (auto instance_it = ds_instances.begin();
+           instance_it != ds_instances.end(); ++instance_it) {
+        if (instance_it->first == it->second.producer_id &&
+            instance_it->second.data_source_name ==
+                cfg_data_source.config().name()) {
+          already_setup = true;
+          break;
+        }
+      }
+
+      if (already_setup)
+        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,
+                      PerfettoStatsdAtom::kTracedStartTracing);
+
+  if (tracing_session->state != TracingSession::CONFIGURED) {
+    MaybeLogUploadEvent(
+        tracing_session->config,
+        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) {
+    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)
+            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 (tracing_session_ptr->config.trigger_config().trigger_mode() ==
+                  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);
+        },
+        trace_duration_ms);
+  }
+
+  // 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->ReadBuffers(tsid, nullptr);
+        },
+        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& kv : tracing_session->data_source_instances) {
+    ProducerID producer_id = kv.first;
+    DataSourceInstance& data_source = kv.second;
+    ProducerEndpointImpl* producer = GetProducer(producer_id);
+    if (!producer) {
+      PERFETTO_DFATAL("Producer does not exist.");
+      continue;
+    }
+    StartDataSourceInstance(producer, tracing_session, &data_source);
+  }
+
+  MaybeNotifyAllDataSourcesStarted(tracing_session);
+  return base::OkStatus();
+}
+
+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,
+                      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;
+
+    // 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::Hash hash;
+    hash.Update(trigger_name.c_str(), trigger_name.size());
+
+    uint64_t trigger_name_hash = hash.digest();
+    size_t count_in_window =
+        PurgeExpiredAndCountTriggerInWindow(now_ns, trigger_name_hash);
+
+    bool trigger_applied = 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 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_applied = true;
+
+      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 (tracing_session.config.trigger_config().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;
+
+          PERFETTO_DLOG("Triggering '%s' on tracing session %" PRIu64
+                        " with duration of %" PRIu32 "ms.",
+                        iter->name().c_str(), tsid, iter->stop_delay_ms());
+          MaybeLogUploadEvent(tracing_session.config,
+                              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;
+
+          PERFETTO_DLOG("Triggering '%s' on tracing session %" PRIu64
+                        " with duration of %" PRIu32 "ms.",
+                        iter->name().c_str(), tsid, iter->stop_delay_ms());
+          MaybeLogUploadEvent(tracing_session.config,
+                              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::UNSPECIFIED:
+          PERFETTO_ELOG("Trigger activated but trigger mode unspecified.");
+          break;
+      }
+    }  // for (.. : tracing_sessions_)
+
+    if (trigger_applied) {
+      trigger_history_.emplace_back(TriggerHistory{now_ns, trigger_name_hash});
+    }
+  }
+}
+
+// Always invoked 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;
+    ReadBuffers(tracing_session->id, nullptr);
+  }
+
+  if (tracing_session->on_disable_callback_for_bugreport) {
+    std::move(tracing_session->on_disable_callback_for_bugreport)();
+    tracing_session->on_disable_callback_for_bugreport = nullptr;
+  }
+
+  MaybeLogUploadEvent(tracing_session->config,
+                      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) {
+  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;
+  }
+
+  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& data_source_inst : tracing_session->data_source_instances) {
+    const ProducerID producer_id = data_source_inst.first;
+    const DataSourceInstanceID ds_inst_id = data_source_inst.second.instance_id;
+    flush_map[producer_id].push_back(ds_inst_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);
+    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 */);
+  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();
+      base::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->uid_, 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->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);
+    }
+  });
+}
+
+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");
+  });
+}
+
+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);
+  }
+}
+
+// Note: when this is called to write into a file passed when starting tracing
+// |consumer| will be == nullptr (as opposite to the case of a consumer asking
+// to send the trace data back over IPC).
+bool TracingServiceImpl::ReadBuffers(TracingSessionID tsid,
+                                     ConsumerEndpointImpl* consumer) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session) {
+    // This will be hit systematically from the PostDelayedTask when directly
+    // writing into the file (in which case consumer == nullptr). Suppress the
+    // log in this case as it's just spam.
+    if (consumer) {
+      PERFETTO_DLOG("Cannot ReadBuffers(): no tracing session is active");
+    }
+    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() &&
+      !tracing_session->seized_for_bugreport) {
+    PERFETTO_DLOG(
+        "ReadBuffers(): tracing session has not received a trigger yet.");
+    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 && !consumer)
+    return false;
+
+  if (tracing_session->write_into_file && consumer) {
+    // 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;
+  }
+
+  std::vector<TracePacket> packets;
+  packets.reserve(1024);  // Just an educated guess to avoid trivial expansions.
+
+  // If a bugreport request happened and the trace was stolen for that, give
+  // an empty trace with a clear signal to the consumer. This deals only with
+  // the case of readback-from-IPC. A similar code-path deals with the
+  // write_into_file case in MaybeSaveTraceForBugreport().
+  if (tracing_session->seized_for_bugreport && consumer) {
+    if (!tracing_session->config.builtin_data_sources()
+             .disable_service_events()) {
+      EmitSeizedForBugreportLifecycleEvent(&packets);
+    }
+    EmitLifecycleEvents(tracing_session, &packets);
+    consumer->consumer_->OnTraceData(std::move(packets), /*has_more=*/false);
+    return true;
+  }
+
+  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->config.builtin_data_sources().disable_system_info())
+    MaybeEmitSystemInfo(tracing_session, &packets);
+
+  // 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|).
+  size_t total_slices = 0;   // SUM(#slices in |packets|).
+
+  // Add up size for packets added by the Maybe* calls above.
+  for (const TracePacket& packet : packets) {
+    packets_bytes += packet.size();
+    total_slices += packet.slices().size();
+  }
+
+  // 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 did_hit_threshold = false;
+
+  // TODO(primiano): Extend the ReadBuffers API to allow reading only some
+  // buffers, not all of them in one go.
+  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;
+      }
+      PERFETTO_DCHECK(sequence_properties.producer_id_trusted != 0);
+      PERFETTO_DCHECK(sequence_properties.writer_id != 0);
+      PERFETTO_DCHECK(sequence_properties.producer_uid_trusted != kInvalidUid);
+      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);
+      trusted_packet->set_trusted_uid(
+          static_cast<int32_t>(sequence_properties.producer_uid_trusted));
+      trusted_packet->set_trusted_packet_sequence_id(
+          tracing_session->GetPacketSequenceID(
+              sequence_properties.producer_id_trusted,
+              sequence_properties.writer_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();
+      total_slices += packet.slices().size();
+      did_hit_threshold = packets_bytes >= kApproxBytesPerTask &&
+                          !tracing_session->write_into_file;
+      packets.emplace_back(std::move(packet));
+    }  // for(packets...)
+  }    // for(buffers...)
+
+  const bool has_more = did_hit_threshold;
+
+  size_t prev_packets_size = packets.size();
+  if (!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;
+  }
+
+  // Add sizes of packets emitted by the EmitLifecycleEvents + EmitStats.
+  for (size_t i = prev_packets_size; i < packets.size(); ++i) {
+    packets_bytes += packets[i].size();
+    total_slices += packets[i].slices().size();
+  }
+
+  // +-------------------------------------------------------------------------+
+  // | NO MORE CHANGES TO |packets| AFTER THIS POINT.                          |
+  // +-------------------------------------------------------------------------+
+
+  // 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) {
+    auto& trace_filter = *tracing_session->trace_filter;
+    // The filter root shoud be reset from protos.Trace to protos.TracePacket
+    // by the earlier call to SetFilterRoot() in EnableTracing().
+    PERFETTO_DCHECK(trace_filter.root_msg_index() != 0);
+    std::vector<protozero::MessageFilter::InputSlice> filter_input;
+    for (auto it = packets.begin(); it != packets.end(); ++it) {
+      const auto& packet_slices = it->slices();
+      filter_input.clear();
+      filter_input.resize(packet_slices.size());
+      ++tracing_session->filter_input_packets;
+      tracing_session->filter_input_bytes += it->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).
+      *it = 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;
+      it->AddSlice(Slice::TakeOwnership(std::move(filtered_packet.data),
+                                        filtered_packet.size));
+
+    }  // for (packet)
+  }    // if (trace_filter)
+
+  // If the caller asked us to write into a file by setting
+  // |write_into_file| == true in the trace config, drain the packets read
+  // (if any) into the given file descriptor.
+  if (tracing_session->write_into_file) {
+    const uint64_t max_size = tracing_session->max_file_size_bytes
+                                  ? tracing_session->max_file_size_bytes
+                                  : std::numeric_limits<size_t>::max();
+
+    // 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 = tracing_session->write_period_ms == 0;
+    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);
+    if (stop_writing_into_file) {
+      // Ensure all data was written to the file before we close it.
+      base::FlushFile(fd);
+      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->ReadBuffers(tsid, nullptr);
+        },
+        tracing_session->delay_to_next_write_period_ms());
+    return true;
+  }  // if (tracing_session->write_into_file)
+
+  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->ReadBuffers(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;
+}
+
+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();
+  bool is_long_trace =
+      (tracing_session->config.write_into_file() &&
+       tracing_session->config.file_write_period_ms() < kMillisPerDay);
+  bool seized_for_bugreport = tracing_session->seized_for_bugreport;
+  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 && (seized_for_bugreport || is_long_trace)) {
+    PERFETTO_LAZY_LOAD(android_internal::NotifyTraceSessionEnded, notify_fn);
+    if (!notify_fn || !notify_fn(seized_for_bugreport))
+      PERFETTO_ELOG("Failed to notify Traceur long tracing has ended");
+  }
+#else
+  base::ignore_result(notify_traceur);
+  base::ignore_result(is_long_trace);
+  base::ignore_result(seized_for_bugreport);
+#endif
+}
+
+void TracingServiceImpl::RegisterDataSource(ProducerID producer_id,
+                                            const DataSourceDescriptor& desc) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Producer %" PRIu16 " registered data source \"%s\"",
+                producer_id, desc.name().c_str());
+
+  PERFETTO_DCHECK(!desc.name().empty());
+  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.
+  if (tracing_sessions_.empty())
+    return;
+
+  ProducerEndpointImpl* producer = GetProducer(producer_id);
+  if (!producer) {
+    PERFETTO_DFATAL("Producer not found.");
+    return;
+  }
+
+  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);
+    }
+  }
+}
+
+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()));
+  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());
+  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,
+    uid_t producer_uid_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.
+  base::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, producer_uid_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;
+}
+
+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);
+
+  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);
+  }
+
+  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).
+  return trace_stats;
+}
+
+void TracingServiceImpl::MaybeEmitTraceConfig(
+    TracingSession* tracing_session,
+    std::vector<TracePacket>* packets) {
+  if (tracing_session->did_emit_config)
+    return;
+  tracing_session->did_emit_config = true;
+  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::MaybeEmitSystemInfo(
+    TracingSession* tracing_session,
+    std::vector<TracePacket>* packets) {
+  if (tracing_session->did_emit_system_info)
+    return;
+  tracing_session->did_emit_system_info = true;
+  protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+  auto* info = packet->set_system_info();
+  info->set_tracing_service_version(base::GetVersionString());
+#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)
+  char value[PROP_VALUE_MAX];
+  if (__system_property_get("ro.build.fingerprint", value)) {
+    info->set_android_build_fingerprint(value);
+  } else {
+    PERFETTO_ELOG("Unable to read ro.build.fingerprint");
+  }
+  info->set_hz(sysconf(_SC_CLK_TCK));
+#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::EmitSeizedForBugreportLifecycleEvent(
+    std::vector<TracePacket>* packets) {
+  protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+  packet->set_timestamp(static_cast<uint64_t>(base::GetBootTimeNs().count()));
+  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(
+      protos::pbzero::TracingServiceEvent::kSeizedForBugreportFieldNumber, 1);
+  SerializeAndAppendPacket(packets, packet.SerializeAsArray());
+}
+
+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;
+  }
+}
+
+bool TracingServiceImpl::MaybeSaveTraceForBugreport(
+    std::function<void()> callback) {
+  TracingSession* max_session = nullptr;
+  TracingSessionID max_tsid = 0;
+  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;
+
+    // Also don't try to steal long traces with write_into_file if their content
+    // has been already partially written into a file, as we would get partial
+    // traces on both sides. We can't just copy the original file into the
+    // bugreport because the file could be too big (GBs) for bugreports.
+    // The only case where it's legit to steal traces with write_into_file, is
+    // when the consumer specified a very large write_period_ms (e.g. 24h),
+    // meaning that this is effectively a ring-buffer trace. Traceur (the
+    // Android System Tracing app), which uses --detach, does this to have a
+    // consistent invocation path for long-traces and ring-buffer-mode traces.
+    if (session.write_into_file && session.bytes_written_into_file > 0)
+      continue;
+
+    // If we are already in the process of finalizing another trace for
+    // bugreport, don't even start another one, as they would try to write onto
+    // the same file.
+    if (session.on_disable_callback_for_bugreport)
+      return false;
+
+    if (!max_session || score > max_session->config.bugreport_score()) {
+      max_session = &session;
+      max_tsid = session_id_and_session.first;
+    }
+  }
+
+  // No eligible trace found.
+  if (!max_session)
+    return false;
+
+  PERFETTO_LOG("Seizing trace for bugreport. tsid:%" PRIu64
+               " state:%d wf:%d score:%d name:\"%s\"",
+               max_tsid, max_session->state, !!max_session->write_into_file,
+               max_session->config.bugreport_score(),
+               max_session->config.unique_session_name().c_str());
+
+  auto br_fd = CreateTraceFile(GetBugreportTmpPath(), /*overwrite=*/true);
+  if (!br_fd)
+    return false;
+
+  if (max_session->write_into_file) {
+    auto fd = *max_session->write_into_file;
+    // If we are stealing a write_into_file session, add a marker that explains
+    // why the trace has been stolen rather than creating an empty file. This is
+    // only for write_into_file traces. A similar code path deals with the case
+    // of reading-back a seized trace from IPC in ReadBuffers().
+    if (!max_session->config.builtin_data_sources().disable_service_events()) {
+      std::vector<TracePacket> packets;
+      EmitSeizedForBugreportLifecycleEvent(&packets);
+      for (auto& packet : packets) {
+        char* preamble;
+        size_t preamble_size = 0;
+        std::tie(preamble, preamble_size) = packet.GetProtoPreamble();
+        base::WriteAll(fd, preamble, preamble_size);
+        for (const Slice& slice : packet.slices()) {
+          base::WriteAll(fd, slice.start, slice.size);
+        }
+      }  // for (packets)
+    }    // if (!disable_service_events())
+  }      // if (max_session->write_into_file)
+  max_session->write_into_file = std::move(br_fd);
+  max_session->on_disable_callback_for_bugreport = std::move(callback);
+  max_session->seized_for_bugreport = true;
+
+  // Post a task to avoid that early FlushAndDisableTracing() failures invoke
+  // the callback before we return. That would re-enter in a weird way the
+  // callstack of the calling ConsumerEndpointImpl::SaveTraceForBugreport().
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this, max_tsid] {
+    if (weak_this)
+      weak_this->FlushAndDisableTracing(max_tsid);
+  });
+  return true;
+}
+
+void TracingServiceImpl::MaybeLogUploadEvent(const TraceConfig& cfg,
+                                             PerfettoStatsdAtom atom,
+                                             const std::string& trigger_name) {
+  if (!ShouldLogEvent(cfg))
+    return;
+
+  // If the UUID is not set for some reason, don't log anything.
+  if (cfg.trace_uuid_lsb() == 0 && cfg.trace_uuid_msb() == 0)
+    return;
+
+  android_stats::MaybeLogUploadEvent(atom, cfg.trace_uuid_lsb(),
+                                     cfg.trace_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;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// 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_->ReadBuffers(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) {
+  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);
+}
+
+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);
+}
+
+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()));
+  }
+
+  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));
+  }
+  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.add_observable_events(ObservableEvents::TYPE_DATA_SOURCES_INSTANCES);
+  caps.add_observable_events(ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED);
+  static_assert(ObservableEvents::Type_MAX ==
+                    ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED,
+                "");
+  callback(caps);
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::SaveTraceForBugreport(
+    SaveTraceForBugreportCallback consumer_callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto on_complete_callback = [consumer_callback] {
+    if (rename(GetBugreportTmpPath().c_str(), GetBugreportPath().c_str())) {
+      consumer_callback(false, "rename(" + GetBugreportTmpPath() + ", " +
+                                   GetBugreportPath() + ") failed (" +
+                                   strerror(errno) + ")");
+    } else {
+      consumer_callback(true, GetBugreportPath());
+    }
+  };
+  if (!service_->MaybeSaveTraceForBugreport(std::move(on_complete_callback))) {
+    consumer_callback(false,
+                      "No trace with TraceConfig.bugreport_score > 0 eligible "
+                      "for bug reporting was found");
+  }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// TracingServiceImpl::ProducerEndpointImpl implementation
+////////////////////////////////////////////////////////////////////////////////
+
+TracingServiceImpl::ProducerEndpointImpl::ProducerEndpointImpl(
+    ProducerID id,
+    uid_t uid,
+    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),
+      uid_(uid),
+      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::RegisterDataSource(
+    const DataSourceDescriptor& desc) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (desc.name().empty()) {
+    PERFETTO_DLOG("Received RegisterDataSource() with empty name");
+    return;
+  }
+
+  service_->RegisterDataSource(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 =
+        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_, uid_, writer_id, chunk_id, buffer_id, num_fragments, chunk_flags,
+        /*chunk_complete=*/true, chunk.payload_begin(), chunk.payload_size());
+
+    // 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);
+  if (in_process_) {
+    inproc_shmem_arbiter_.reset(new SharedMemoryArbiterImpl(
+        shared_memory_->start(), shared_memory_->size(),
+        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) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this, flush_request_id, data_sources] {
+    if (weak_this) {
+      weak_this->producer_->Flush(flush_request_id, data_sources.data(),
+                                  data_sources.size());
+    }
+  });
+}
+
+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) {
+      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) {
+  // 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/shared_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.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 {
+
+namespace {
+
+class InProcessShm : public SharedMemory {
+ public:
+  explicit InProcessShm(size_t size);
+  ~InProcessShm() override;
+  void* start() const override;
+  size_t size() const override;
+
+ private:
+  base::PagedMemory mem_;
+};
+
+class InProcessShmFactory : public SharedMemory::Factory {
+ public:
+  ~InProcessShmFactory() override;
+  std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) override;
+};
+
+InProcessShm::~InProcessShm() = default;
+
+InProcessShm::InProcessShm(size_t size)
+    : mem_(base::PagedMemory::Allocate(size)) {}
+
+void* InProcessShm::start() const {
+  return mem_.Get();
+}
+
+size_t InProcessShm::size() const {
+  return mem_.size();
+}
+
+InProcessShmFactory::~InProcessShmFactory() = default;
+std::unique_ptr<SharedMemory> InProcessShmFactory::CreateSharedMemory(
+    size_t size) {
+  return std::unique_ptr<SharedMemory>(new InProcessShm(size));
+}
+
+}  // namespace
+
+// 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());
+
+  // This should never happen as we can have at most one in-process backend.
+  if (service_)
+    PERFETTO_FATAL("InProcessTracingBackend initialized twice");
+
+  return GetOrCreateService(args.task_runner)
+      ->ConnectProducer(args.producer, /*uid=*/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<InProcessShmFactory> shm(new InProcessShmFactory());
+    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 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 SaveTraceForBugreportResponse;
+class SaveTraceForBugreportRequest;
+class QueryCapabilitiesResponse;
+class TracingServiceCapabilities;
+class QueryCapabilitiesRequest;
+class QueryServiceStateResponse;
+class TracingServiceState;
+class TracingServiceState_DataSource;
+class DataSourceDescriptor;
+class TracingServiceState_Producer;
+class QueryServiceStateRequest;
+class ObserveEventsResponse;
+class ObservableEvents;
+class ObservableEvents_DataSourceInstanceStateChange;
+class ObserveEventsRequest;
+class GetTraceStatsResponse;
+class TraceStats;
+class TraceStats_FilterStats;
+class TraceStats_BufferStats;
+class GetTraceStatsRequest;
+class AttachResponse;
+class TraceConfig;
+class TraceConfig_TraceFilter;
+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 ChromeConfig;
+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 TraceConfig_LockdownModeOperation : int;
+enum TraceConfig_CompressionType : int;
+enum TraceConfig_StatsdLogging : int;
+enum TraceConfig_TriggerConfig_TriggerMode : int;
+enum BuiltinClock : int;
+enum DataSourceConfig_SessionInitiator : 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 FlushRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTimeoutMsFieldNumber = 1,
+  };
+
+  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); }
+
+ private:
+  uint32_t timeout_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 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 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 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 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 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 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 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 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 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 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 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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/common/builtin_clock.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.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/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/chrome/chrome_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_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/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/observable_events.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+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 unknown_fields_ == other.unknown_fields_
+   && success_ == other.success_
+   && 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 */:
+        field.get(&msg_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SaveTraceForBugreportResponse::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SaveTraceForBugreportResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SaveTraceForBugreportResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: success
+  if (_has_field_[1]) {
+    msg->AppendTinyVarInt(1, success_);
+  }
+
+  // Field 2: msg
+  if (_has_field_[2]) {
+    msg->AppendString(2, msg_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SaveTraceForBugreportRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SaveTraceForBugreportRequest::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> QueryCapabilitiesResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> QueryCapabilitiesRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void QueryCapabilitiesRequest::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> QueryServiceStateResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> QueryServiceStateRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void QueryServiceStateRequest::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ObserveEventsResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ObserveEventsRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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_) {
+    msg->AppendVarInt(1, it);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetTraceStatsResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetTraceStatsRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetTraceStatsRequest::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AttachResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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 */:
+        field.get(&key_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AttachRequest::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AttachRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AttachRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: key
+  if (_has_field_[1]) {
+    msg->AppendString(1, key_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DetachResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DetachResponse::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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 */:
+        field.get(&key_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DetachRequest::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DetachRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DetachRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: key
+  if (_has_field_[1]) {
+    msg->AppendString(1, key_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FlushResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FlushResponse::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && timeout_ms_ == other.timeout_ms_;
+}
+
+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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FlushRequest::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FlushRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FlushRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: timeout_ms
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, timeout_ms_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FreeBuffersResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FreeBuffersResponse::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FreeBuffersRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FreeBuffersRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: buffer_ids
+  for (auto& it : buffer_ids_) {
+    msg->AppendVarInt(1, it);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ReadBuffersResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && data_ == other.data_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ReadBuffersResponse_Slice::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ReadBuffersResponse_Slice::Serialize(::protozero::Message* msg) const {
+  // Field 1: data
+  if (_has_field_[1]) {
+    msg->AppendString(1, data_);
+  }
+
+  // Field 2: last_slice_for_packet
+  if (_has_field_[2]) {
+    msg->AppendTinyVarInt(2, last_slice_for_packet_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ReadBuffersRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ReadBuffersRequest::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DisableTracingResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DisableTracingResponse::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DisableTracingRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DisableTracingRequest::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChangeTraceConfigResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChangeTraceConfigResponse::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChangeTraceConfigRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> StartTracingResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void StartTracingResponse::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> StartTracingRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void StartTracingRequest::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && disabled_ == other.disabled_
+   && 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 */:
+        field.get(&error_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string EnableTracingResponse::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EnableTracingResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void EnableTracingResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: disabled
+  if (_has_field_[1]) {
+    msg->AppendTinyVarInt(1, disabled_);
+  }
+
+  // Field 3: error
+  if (_has_field_[3]) {
+    msg->AppendString(3, error_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && trace_config_ == other.trace_config_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EnableTracingRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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]) {
+    msg->AppendTinyVarInt(2, attach_notification_only_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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 ChromeConfig;
+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 RegisterDataSourceResponse;
+class RegisterDataSourceRequest;
+class DataSourceDescriptor;
+class InitializeConnectionResponse;
+class InitializeConnectionRequest;
+enum DataSourceConfig_SessionInitiator : int;
+enum ChromeConfig_ClientPriority : int;
+enum InitializeConnectionRequest_ProducerSMBScrapingMode : int;
+enum InitializeConnectionRequest_ProducerBuildFlags : 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,
+};
+enum InitializeConnectionRequest_ProducerBuildFlags : int {
+  InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_UNSPECIFIED = 0,
+  InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_ON = 1,
+  InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_OFF = 2,
+};
+
+class PERFETTO_EXPORT 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 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 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 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 GetAsyncCommandResponse_Flush : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDataSourceIdsFieldNumber = 1,
+    kRequestIdFieldNumber = 2,
+  };
+
+  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); }
+
+ private:
+  std::vector<uint64_t> data_source_ids_;
+  uint64_t request_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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 InitializeConnectionResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kUsingShmemProvidedByProducerFieldNumber = 1,
+    kDirectSmbPatchingSupportedFieldNumber = 2,
+  };
+
+  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); }
+
+ private:
+  bool using_shmem_provided_by_producer_{};
+  bool direct_smb_patching_supported_{};
+
+  // 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 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;
+  using ProducerBuildFlags = InitializeConnectionRequest_ProducerBuildFlags;
+  static constexpr auto BUILD_FLAGS_UNSPECIFIED = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_UNSPECIFIED;
+  static constexpr auto BUILD_FLAGS_DCHECKS_ON = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_ON;
+  static constexpr auto BUILD_FLAGS_DCHECKS_OFF = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_OFF;
+  static constexpr auto ProducerBuildFlags_MIN = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_UNSPECIFIED;
+  static constexpr auto ProducerBuildFlags_MAX = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_OFF;
+  enum FieldNumbers {
+    kSharedMemoryPageSizeHintBytesFieldNumber = 1,
+    kSharedMemorySizeHintBytesFieldNumber = 2,
+    kProducerNameFieldNumber = 3,
+    kSmbScrapingModeFieldNumber = 4,
+    kBuildFlagsFieldNumber = 5,
+    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_build_flags() const { return _has_field_[5]; }
+  InitializeConnectionRequest_ProducerBuildFlags build_flags() const { return build_flags_; }
+  void set_build_flags(InitializeConnectionRequest_ProducerBuildFlags value) { build_flags_ = value; _has_field_.set(5); }
+
+  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_{};
+  InitializeConnectionRequest_ProducerBuildFlags build_flags_{};
+  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 expanded: #include "perfetto/protozero/message.h"
+// gen_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/config/data_source_config.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/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/chrome/chrome_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_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/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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SyncResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SyncResponse::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SyncRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SyncRequest::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && setup_tracing_ == other.setup_tracing_
+   && setup_data_source_ == other.setup_data_source_
+   && start_data_source_ == other.start_data_source_
+   && stop_data_source_ == other.stop_data_source_
+   && flush_ == other.flush_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse_ClearIncrementalState::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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_) {
+    msg->AppendVarInt(1, it);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && data_source_ids_ == other.data_source_ids_
+   && request_id_ == other.request_id_;
+}
+
+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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetAsyncCommandResponse_Flush::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse_Flush::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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_) {
+    msg->AppendVarInt(1, it);
+  }
+
+  // Field 2: request_id
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, request_id_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse_StopDataSource::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandResponse_StopDataSource::Serialize(::protozero::Message* msg) const {
+  // Field 1: instance_id
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, instance_id_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && new_instance_id_ == other.new_instance_id_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse_StartDataSource::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandResponse_StartDataSource::Serialize(::protozero::Message* msg) const {
+  // Field 1: new_instance_id
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, new_instance_id_);
+  }
+
+  // Field 2: config
+  if (_has_field_[2]) {
+    (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && new_instance_id_ == other.new_instance_id_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse_SetupDataSource::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandResponse_SetupDataSource::Serialize(::protozero::Message* msg) const {
+  // Field 1: new_instance_id
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, new_instance_id_);
+  }
+
+  // Field 2: config
+  if (_has_field_[2]) {
+    (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && shared_buffer_page_size_kb_ == other.shared_buffer_page_size_kb_
+   && 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 */:
+        field.get(&shm_key_windows_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetAsyncCommandResponse_SetupTracing::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse_SetupTracing::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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]) {
+    msg->AppendVarInt(1, shared_buffer_page_size_kb_);
+  }
+
+  // Field 2: shm_key_windows
+  if (_has_field_[2]) {
+    msg->AppendString(2, shm_key_windows_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandRequest::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ActivateTriggersResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ActivateTriggersResponse::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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();
+        field.get(&trigger_names_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ActivateTriggersRequest::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ActivateTriggersRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ActivateTriggersRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: trigger_names
+  for (auto& it : trigger_names_) {
+    msg->AppendString(1, it);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> NotifyDataSourceStoppedResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void NotifyDataSourceStoppedResponse::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> NotifyDataSourceStoppedRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void NotifyDataSourceStoppedRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: data_source_id
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, data_source_id_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> NotifyDataSourceStartedResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void NotifyDataSourceStartedResponse::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> NotifyDataSourceStartedRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void NotifyDataSourceStartedRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: data_source_id
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, data_source_id_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CommitDataResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CommitDataResponse::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UnregisterTraceWriterResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UnregisterTraceWriterResponse::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UnregisterTraceWriterRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UnregisterTraceWriterRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_writer_id
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, trace_writer_id_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> RegisterTraceWriterResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void RegisterTraceWriterResponse::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && trace_writer_id_ == other.trace_writer_id_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> RegisterTraceWriterRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void RegisterTraceWriterRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_writer_id
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, trace_writer_id_);
+  }
+
+  // Field 2: target_buffer
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, target_buffer_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UnregisterDataSourceResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UnregisterDataSourceResponse::Serialize(::protozero::Message* msg) const {
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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 */:
+        field.get(&data_source_name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string UnregisterDataSourceRequest::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UnregisterDataSourceRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UnregisterDataSourceRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: data_source_name
+  if (_has_field_[1]) {
+    msg->AppendString(1, data_source_name_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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 */:
+        field.get(&error_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string RegisterDataSourceResponse::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> RegisterDataSourceResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void RegisterDataSourceResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: error
+  if (_has_field_[1]) {
+    msg->AppendString(1, error_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> RegisterDataSourceRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && using_shmem_provided_by_producer_ == other.using_shmem_provided_by_producer_
+   && direct_smb_patching_supported_ == other.direct_smb_patching_supported_;
+}
+
+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;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string InitializeConnectionResponse::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> InitializeConnectionResponse::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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]) {
+    msg->AppendTinyVarInt(1, using_shmem_provided_by_producer_);
+  }
+
+  // Field 2: direct_smb_patching_supported
+  if (_has_field_[2]) {
+    msg->AppendTinyVarInt(2, direct_smb_patching_supported_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && shared_memory_page_size_hint_bytes_ == other.shared_memory_page_size_hint_bytes_
+   && shared_memory_size_hint_bytes_ == other.shared_memory_size_hint_bytes_
+   && producer_name_ == other.producer_name_
+   && smb_scraping_mode_ == other.smb_scraping_mode_
+   && build_flags_ == other.build_flags_
+   && producer_provided_shmem_ == other.producer_provided_shmem_
+   && sdk_version_ == other.sdk_version_
+   && 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 */:
+        field.get(&producer_name_);
+        break;
+      case 4 /* smb_scraping_mode */:
+        field.get(&smb_scraping_mode_);
+        break;
+      case 5 /* build_flags */:
+        field.get(&build_flags_);
+        break;
+      case 6 /* producer_provided_shmem */:
+        field.get(&producer_provided_shmem_);
+        break;
+      case 8 /* sdk_version */:
+        field.get(&sdk_version_);
+        break;
+      case 7 /* shm_key_windows */:
+        field.get(&shm_key_windows_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string InitializeConnectionRequest::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> InitializeConnectionRequest::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> 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]) {
+    msg->AppendVarInt(1, shared_memory_page_size_hint_bytes_);
+  }
+
+  // Field 2: shared_memory_size_hint_bytes
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, shared_memory_size_hint_bytes_);
+  }
+
+  // Field 3: producer_name
+  if (_has_field_[3]) {
+    msg->AppendString(3, producer_name_);
+  }
+
+  // Field 4: smb_scraping_mode
+  if (_has_field_[4]) {
+    msg->AppendVarInt(4, smb_scraping_mode_);
+  }
+
+  // Field 5: build_flags
+  if (_has_field_[5]) {
+    msg->AppendVarInt(5, build_flags_);
+  }
+
+  // Field 6: producer_provided_shmem
+  if (_has_field_[6]) {
+    msg->AppendTinyVarInt(6, producer_provided_shmem_);
+  }
+
+  // Field 8: sdk_version
+  if (_has_field_[8]) {
+    msg->AppendString(8, sdk_version_);
+  }
+
+  // Field 7: shm_key_windows
+  if (_has_field_[7]) {
+    msg->AppendString(7, shm_key_windows_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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 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_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 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;
+  enum FieldNumbers {
+    kRequestIdFieldNumber = 2,
+    kMsgBindServiceFieldNumber = 3,
+    kMsgBindServiceReplyFieldNumber = 4,
+    kMsgInvokeMethodFieldNumber = 5,
+    kMsgInvokeMethodReplyFieldNumber = 6,
+    kMsgRequestErrorFieldNumber = 7,
+    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(); }
+
+  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_;
+  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<8> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT 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 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 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 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 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 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 expanded: #include "perfetto/protozero/message.h"
+// gen_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 unknown_fields_ == other.unknown_fields_
+   && request_id_ == other.request_id_
+   && msg_bind_service_ == other.msg_bind_service_
+   && msg_bind_service_reply_ == other.msg_bind_service_reply_
+   && msg_invoke_method_ == other.msg_invoke_method_
+   && msg_invoke_method_reply_ == other.msg_invoke_method_reply_
+   && msg_request_error_ == other.msg_request_error_
+   && 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 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame::Serialize(::protozero::Message* msg) const {
+  // Field 2: request_id
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, request_id_);
+  }
+
+  // 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 1: data_for_testing
+  for (auto& it : data_for_testing_) {
+    msg->AppendString(1, it);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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 */:
+        field.get(&error_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string IPCFrame_RequestError::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_RequestError::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_RequestError::Serialize(::protozero::Message* msg) const {
+  // Field 1: error
+  if (_has_field_[1]) {
+    msg->AppendString(1, error_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && success_ == other.success_
+   && has_more_ == other.has_more_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_InvokeMethodReply::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_InvokeMethodReply::Serialize(::protozero::Message* msg) const {
+  // Field 1: success
+  if (_has_field_[1]) {
+    msg->AppendTinyVarInt(1, success_);
+  }
+
+  // Field 2: has_more
+  if (_has_field_[2]) {
+    msg->AppendTinyVarInt(2, has_more_);
+  }
+
+  // Field 3: reply_proto
+  if (_has_field_[3]) {
+    msg->AppendString(3, reply_proto_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && service_id_ == other.service_id_
+   && method_id_ == other.method_id_
+   && args_proto_ == other.args_proto_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_InvokeMethod::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_InvokeMethod::Serialize(::protozero::Message* msg) const {
+  // Field 1: service_id
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, service_id_);
+  }
+
+  // Field 2: method_id
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, method_id_);
+  }
+
+  // Field 3: args_proto
+  if (_has_field_[3]) {
+    msg->AppendString(3, args_proto_);
+  }
+
+  // Field 4: drop_reply
+  if (_has_field_[4]) {
+    msg->AppendTinyVarInt(4, drop_reply_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && success_ == other.success_
+   && service_id_ == other.service_id_
+   && 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::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_BindServiceReply::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_BindServiceReply::Serialize(::protozero::Message* msg) const {
+  // Field 1: success
+  if (_has_field_[1]) {
+    msg->AppendTinyVarInt(1, success_);
+  }
+
+  // Field 2: service_id
+  if (_has_field_[2]) {
+    msg->AppendVarInt(2, service_id_);
+  }
+
+  // Field 3: methods
+  for (auto& it : methods_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && id_ == other.id_
+   && 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 */:
+        field.get(&name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string IPCFrame_BindServiceReply_MethodInfo::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_BindServiceReply_MethodInfo::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_BindServiceReply_MethodInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: id
+  if (_has_field_[1]) {
+    msg->AppendVarInt(1, id_);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    msg->AppendString(2, name_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+
+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 unknown_fields_ == other.unknown_fields_
+   && 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 */:
+        field.get(&service_name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string IPCFrame_BindService::SerializeAsString() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_BindService::SerializeAsArray() const {
+  ::protozero::HeapBuffered<::protozero::Message> msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_BindService::Serialize(::protozero::Message* msg) const {
+  // Field 1: service_name
+  if (_has_field_[1]) {
+    msg->AppendString(1, service_name_);
+  }
+
+  msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
+}
+
+}  // 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>
+
+// 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/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 SocketHandle and ScopedSocketHandle types.
+// On POSIX OSes, a SocketHandle is really just an int (a file descriptor).
+// On Windows, sockets are have their own type (SOCKET) which is neither a
+// HANDLE nor an int. However Windows SOCKET(s) can have a event HANDLE attached
+// to them (which in Perfetto is a PlatformHandle), and that can be used in
+// WaitForMultipleObjects, hence in base::TaskRunner.AddFileDescriptorWatch().
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// uintptr_t really reads as SOCKET here (Windows headers typedef to that).
+// As usual we don't just use SOCKET here to avoid leaking Windows.h includes
+// in our headers.
+using SocketHandle = uintptr_t;  // SOCKET
+int CloseSocket(SocketHandle);   // A wrapper around ::closesocket().
+using ScopedSocketHandle =
+    ScopedResource<SocketHandle, CloseSocket, static_cast<SocketHandle>(-1)>;
+#else
+using SocketHandle = int;
+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 GetSockType() / GetSockFamily().
+enum class SockType { kStream = 100, kDgram, kSeqPacket };
+enum class SockFamily { kUnix = 200, kInet, kInet6 };
+
+// Controls the getsockopt(SO_PEERCRED) behavior, which allows to obtain the
+// peer credentials.
+enum class SockPeerCredMode {
+  // Obtain the peer credentials immediatley 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)
+  kDefault = kIgnore,
+#else
+  kDefault = kReadOnConnect,
+#endif
+};
+
+// 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 RetainOnExec();
+  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);
+
+  // |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;
+};
+
+// 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 UnixSocket {
+ public:
+  class EventListener {
+   public:
+    virtual ~EventListener();
+
+    // After Listen().
+    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));
+  }
+  // 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 Send(const std::string& msg) {
+    return Send(msg.c_str(), msg.size() + 1, -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(); }
+
+  // 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)
+  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)
+  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_
+/*
+ * 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"
+
+#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 <netdb.h>
+#include <netinet/in.h>
+#include <netinet/tcp.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/ext/base/string_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+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 {
+
+// MSG_NOSIGNAL is not supported on Mac OS X, but in that case the socket is
+// created with SO_NOSIGPIPE (See InitializeSocket()).
+// On Windows this does't apply as signals don't exist.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+constexpr int kNoSigPipe = 0;
+#else
+constexpr int kNoSigPipe = MSG_NOSIGNAL;
+#endif
+
+// 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
+
+// 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 GetSockFamily(SockFamily family) {
+  switch (family) {
+    case SockFamily::kUnix:
+      return AF_UNIX;
+    case SockFamily::kInet:
+      return AF_INET;
+    case SockFamily::kInet6:
+      return AF_INET6;
+  }
+  PERFETTO_CHECK(false);  // For GCC.
+}
+
+inline int GetSockType(SockType type) {
+#ifdef 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 >= 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);
+      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;
+    }
+  }
+  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(GetSockFamily(family), GetSockType(type), 0));
+}
+
+}  // namespace
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+int CloseSocket(SocketHandle s) {
+  return ::closesocket(s);
+}
+#endif
+
+// +-----------------------+
+// | 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(GetSockFamily(family), GetSockType(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) {
+    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)));
+    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.
+  int fcntl_res = fcntl(*fd_, F_SETFD, FD_CLOEXEC);
+  PERFETTO_CHECK(fcntl_res == 0);
+#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::RetainOnExec() {
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  PERFETTO_DCHECK(fd_);
+  int flags = fcntl(*fd_, F_GETFD, 0);
+  flags &= ~static_cast<int>(FD_CLOEXEC);
+  int fcntl_res = fcntl(*fd_, F_SETFD, flags);
+  PERFETTO_CHECK(fcntl_res == 0);
+#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_);
+
+  ssize_t total_sent = 0;
+  while (msg->msg_iov) {
+    ssize_t sent = PERFETTO_EINTR(sendmsg(*fd_, msg, kNoSigPipe));
+    if (sent <= 0) {
+      if (sent == -1 && IsAgain(errno))
+        return total_sent;
+      return sent;
+    }
+    total_sent += sent;
+    ShiftMsgHdrPosix(static_cast<size_t>(sent), 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_);
+#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_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;
+}
+
+#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
+// On Android, Linux, Mac use a AF_UNIX socket.
+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);
+
+  template <typename T>
+  explicit DeferredBase(Deferred<T> other)
+      : callback_(std::move(other.callback_)) {}
+
+  ~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|.
+  };
+
+  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*);
+
+  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;
+};
+
+}  // 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/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)
+      : client_id_(client_id), uid_(uid) {}
+
+  bool operator==(const ClientInfo& other) const {
+    return (client_id_ == other.client_id_ && uid_ == other.uid_);
+  }
+  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_; }
+
+ private:
+  ClientID client_id_ = 0;
+  uid_t uid_ = kInvalidUid;
+};
+
+}  // 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();
+  }
+
+ 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_;
+};
+
+}  // 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 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_,
+                                    kClientSockFamily, 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();
+    });
+  }
+  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/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 {
+
+class HostImpl : public Host, public base::UnixSocket::EventListener {
+ public:
+  HostImpl(const char* socket_name, base::TaskRunner*);
+  HostImpl(base::ScopedSocketHandle, base::TaskRunner*);
+  ~HostImpl() override;
+
+  // Host implementation.
+  bool ExposeService(std::unique_ptr<Service>) 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;
+  };
+  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 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;
+  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/task_runner.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;
+
+uid_t GetPosixPeerUid(base::UnixSocket* sock) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  base::ignore_result(sock);
+  // Unsupported. Must be != kInvalidUid or the PacketValidator will fail.
+  return 0;
+#else
+  return sock->peer_uid_posix();
+#endif
+}
+
+}  // namespace
+
+// 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));
+}
+
+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_,
+                                   kHostSockFamily, base::SockType::kStream);
+  if (!sock_) {
+    PERFETTO_PLOG("Failed to create %s", socket_name);
+  }
+}
+
+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;
+  }
+  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::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);
+  // Watchdog is 30 seconds, so set the socket timeout to 10 seconds.
+  client->sock->SetTxTimeout(10000);
+  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;
+
+  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);
+
+  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));
+    });
+  }
+
+  service->client_info_ =
+      ClientInfo(client->id, GetPosixPeerUid(client->sock.get()));
+  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::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) {
+  std::string buf = BufferedFrameDeserializer::Serialize(frame);
+
+  // 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;
+  ClientID client_id = it->second->id;
+
+  ClientInfo client_info(client_id, GetPosixPeerUid(sock));
+  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;
+
+};
+
+
+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);
+
+};
+
+}  // 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.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);
+}
+}  // 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;
+
+};
+
+
+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);
+
+};
+
+}  // 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.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);
+}
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+// gen_amalgamated begin source: src/tracing/ipc/default_socket.cc
+// gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/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_EXT_TRACING_IPC_DEFAULT_SOCKET_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_IPC_DEFAULT_SOCKET_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+
+PERFETTO_EXPORT const char* GetConsumerSocket();
+PERFETTO_EXPORT const char* GetProducerSocket();
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/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/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
+
+static_assert(kInvalidUid == ipc::kInvalidUid, "kInvalidUid mismatching");
+
+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* 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)
+
+#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)
+
+#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)
+
+// 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.
+  static std::unique_ptr<SharedMemoryWindows> Create(size_t size);
+  static std::unique_ptr<SharedMemoryWindows> Attach(const std::string& key);
+  ~SharedMemoryWindows() override;
+  const std::string& key() const { return key_; }
+
+  // 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) {
+  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);
+  shmem_handle.reset(CreateFileMappingA(
+      INVALID_HANDLE_VALUE,  // Use paging file.
+      nullptr,               // Default security.
+      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)));
+}
+
+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 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) 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;
+
+  // 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) {
+  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));
+  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 succesfully, 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));
+}
+
+}  // 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"
+
+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 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);
+
+ 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/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.
+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);
+  ~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 RegisterDataSource(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:
+  // 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);
+
+  // 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_;
+
+  // 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.
+  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;
+  std::vector<std::function<void()>> pending_sync_reqs_;
+  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/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_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"
+
+#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)));
+}
+
+// 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) {
+  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)));
+}
+
+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)
+    : producer_(producer),
+      task_runner_(task_runner),
+      ipc_channel_(
+          ipc::Client::CreateInstance(std::move(conn_args), task_runner)),
+      producer_port_(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;
+  }
+
+  ipc_channel_->BindService(producer_port_.GetWeakPtr());
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+}
+
+ProducerIPCClientImpl::~ProducerIPCClientImpl() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+}
+
+// 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);
+      });
+  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
+  }
+
+#if PERFETTO_DCHECK_IS_ON()
+  req.set_build_flags(
+      protos::gen::InitializeConnectionRequest::BUILD_FLAGS_DCHECKS_ON);
+#else
+  req.set_build_flags(
+      protos::gen::InitializeConnectionRequest::BUILD_FLAGS_DCHECKS_OFF);
+#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::OnConnectionInitialized(
+    bool connection_succeeded,
+    bool using_shmem_provided_by_producer,
+    bool direct_smb_patching_supported) {
+  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;
+  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.");
+    ipc_channel_.reset();
+    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);
+#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 (ipc_shared_memory) {
+      // 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, 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");
+    producer_->Flush(
+        cmd.flush().request_id(),
+        reinterpret_cast<const DataSourceInstanceID*>(data_source_ids),
+        static_cast<size_t>(cmd.flush().data_source_ids().size()));
+    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::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 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 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;
+
+    // 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));
+  };
+  GetConsumerForCurrentRequest()->service_endpoint->Flush(req.timeout_ms(),
+                                                          std::move(callback));
+}
+
+// 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);
+}
+
+// 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));
+}
+
+}  // 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 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) 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/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 PERFETTO_DCHECK_IS_ON()
+  if (req.build_flags() ==
+      protos::gen::InitializeConnectionRequest::BUILD_FLAGS_DCHECKS_OFF) {
+    PERFETTO_LOG(
+        "The producer is built with NDEBUG but the service binary was built "
+        "with the DEBUG flag. This will likely cause crashes.");
+    // The other way round (DEBUG producer with NDEBUG service) is expected to
+    // work.
+  }
+#endif
+
+  // 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
+  }
+
+  // ConnectProducer will call OnConnect() on the next task.
+  producer->service_endpoint = core_service_->ConnectProducer(
+      producer.get(), client_info.uid(), 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 using_producer_shmem =
+      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);
+  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 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) {
+  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);
+  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
+/*
+ * 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"
+
+namespace perfetto {
+namespace base {
+class TaskRunner;
+}  // namespace base.
+
+class TracingService;
+
+// 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 ServiceIPCHost {
+ public:
+  static std::unique_ptr<ServiceIPCHost> CreateInstance(base::TaskRunner*);
+  virtual ~ServiceIPCHost();
+
+  // 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 char* producer_socket_name,
+                     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;
+
+  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:
+  ServiceIPCHostImpl(base::TaskRunner*);
+  ~ServiceIPCHostImpl() override;
+
+  // ServiceIPCHost implementation.
+  bool Start(const char* producer_socket_name,
+             const char* consumer_socket_name) override;
+  bool Start(base::ScopedSocketHandle producer_socket_fd,
+             base::ScopedSocketHandle consumer_socket_fd) override;
+
+  TracingService* service() const override;
+
+ private:
+  bool DoStart();
+  void Shutdown();
+
+  base::TaskRunner* const task_runner_;
+  std::unique_ptr<TracingService> svc_;  // The service business logic.
+
+  // The IPC host that listens on the Producer socket. It owns the
+  // PosixServiceProducerPort instance which deals with all producers' IPC(s).
+  std::unique_ptr<ipc::Host> producer_ipc_port_;
+
+  // 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/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 {
+
+// 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) {
+  return std::unique_ptr<ServiceIPCHost>(new ServiceIPCHostImpl(task_runner));
+}
+
+ServiceIPCHostImpl::ServiceIPCHostImpl(base::TaskRunner* task_runner)
+    : task_runner_(task_runner) {}
+
+ServiceIPCHostImpl::~ServiceIPCHostImpl() {}
+
+bool ServiceIPCHostImpl::Start(const char* producer_socket_name,
+                               const char* consumer_socket_name) {
+  PERFETTO_CHECK(!svc_);  // Check if already started.
+
+  // Initialize the IPC transport.
+  producer_ipc_port_ =
+      ipc::Host::CreateInstance(producer_socket_name, 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_port_ =
+      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::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_);
+
+  if (!producer_ipc_port_ || !consumer_ipc_port_) {
+    Shutdown();
+    return false;
+  }
+
+  // TODO(fmayer): add a test that destroyes the ServiceIPCHostImpl soon after
+  // Start() and checks that no spurious callbacks are issued.
+  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_port_.reset();
+  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/consumer_ipc_client.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/default_socket.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/producer_ipc_client.h"
+
+namespace perfetto {
+namespace internal {
+
+// static
+TracingBackend* SystemTracingBackend::GetInstance() {
+  static auto* instance = new SystemTracingBackend();
+  return instance;
+}
+
+SystemTracingBackend::SystemTracingBackend() {}
+
+std::unique_ptr<ProducerEndpoint> SystemTracingBackend::ConnectProducer(
+    const ConnectProducerArgs& args) {
+  PERFETTO_DCHECK(args.task_runner->RunsTasksOnCurrentThread());
+
+  auto endpoint = ProducerIPCClient::Connect(
+      GetProducerSocket(), args.producer, args.producer_name, args.task_runner,
+      TracingService::ProducerSMBScrapingMode::kEnabled,
+      args.shmem_size_hint_bytes, args.shmem_page_size_hint_bytes, nullptr,
+      nullptr, ProducerIPCClient::ConnectionFlags::kRetryIfUnreachable);
+  PERFETTO_CHECK(endpoint);
+  return endpoint;
+}
+
+std::unique_ptr<ConsumerEndpoint> SystemTracingBackend::ConnectConsumer(
+    const ConnectConsumerArgs& args) {
+  auto endpoint = ConsumerIPCClient::Connect(GetConsumerSocket(), args.consumer,
+                                             args.task_runner);
+  PERFETTO_CHECK(endpoint);
+  return endpoint;
+}
+
+}  // 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_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;
+
+ 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(tls_key_);
+  g_instance = nullptr;
+}
+
+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
+// 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 module, DWORD reason, PVOID reserved) {
+  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..10df532
--- /dev/null
+++ b/sdk/perfetto.h
@@ -0,0 +1,132578 @@
+// 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/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/base/compiler.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_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() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TRACED_PERF() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_HEAPPROFD() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_STDERR_CRASH_DUMP() (0)
+
+// 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
+
+// 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 amaglamated 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_
+/*
+ * 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/base/build_config.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_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
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+#define PERFETTO_WARN_UNUSED_RESULT
+#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 PERFETTO_BUILDFLAG(PERFETTO_OS_IOS)
+// TODO(b/158814068): For iOS builds, thread_local is only supported since iOS
+// 8. We'd have to use pthread for thread local data instead here. For now, just
+// define it to nothing since we don't support running perfetto or the client
+// lib on iOS right now.
+#define PERFETTO_THREAD_LOCAL
+#else
+#define PERFETTO_THREAD_LOCAL thread_local
+#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
+
+// 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
+
+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/logging.h
+// gen_amalgamated begin header: include/perfetto/base/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"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_COMPONENT_BUILD)
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#if defined(PERFETTO_IMPLEMENTATION)
+#define PERFETTO_EXPORT __declspec(dllexport)
+#else
+#define PERFETTO_EXPORT __declspec(dllimport)
+#endif
+
+#else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#if defined(PERFETTO_IMPLEMENTATION)
+#define PERFETTO_EXPORT __attribute__((visibility("default")))
+#else
+#define PERFETTO_EXPORT
+#endif
+
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#else  // !PERFETTO_BUILDFLAG(PERFETTO_COMPONENT_BUILD)
+
+#define PERFETTO_EXPORT
+
+#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
+
+// TODO(primiano): move this to base/build_config.h, turn into
+// PERFETTO_BUILDFLAG(DCHECK_IS_ON) and update call sites to use that instead.
+#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
+#define PERFETTO_DCHECK_IS_ON() 0
+#else
+#define PERFETTO_DCHECK_IS_ON() 1
+#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
+
+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 void SetLogMessageCallback(LogMessageCallback callback);
+
+PERFETTO_EXPORT void LogMessage(LogLev,
+                                const char* fname,
+                                int line,
+                                const char* fmt,
+                                ...) PERFETTO_PRINTF_FORMAT(4, 5);
+
+#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(...) ::perfetto::base::ignore_result(__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 {                             \
+    __debugbreak();                \
+    __assume(0);                   \
+  } while (0)
+#else
+#define PERFETTO_IMMEDIATE_CRASH() \
+  do {                             \
+    __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_
+// 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
+/*
+ * 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"
+
+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;
+
+// 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 and 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>
+inline uint8_t* WriteVarInt(T value, uint8_t* target) {
+  // 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);
+
+  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) {
+  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 |= 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;
+}
+
+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 internal {
+
+// Ideally we would create variables of FieldMetadata<...> type directly,
+// but before C++17's support for constexpr inline variables arrive, we have to
+// actually use pointers to inline functions instead to avoid having to define
+// symbols in *.pbzero.cc files.
+//
+// Note: protozero bindings will generate Message::kFieldName variable and which
+// can then be passed to TRACE_EVENT macro for inline writing of typed messages.
+// The fact that the former can be passed to the latter is a part of the stable
+// API, while the particular type is not and users should not rely on it.
+template <typename T>
+using FieldMetadataHelper = T (*)(void);
+
+}  // namespace internal
+}  // 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; }
+  uint16_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(uint16_t id,
+                  uint8_t type,
+                  uint64_t int_value,
+                  uint32_t size) {
+    id_ = id;
+    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;
+
+ 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.
+  uint16_t id_;         // Proto field ordinal.
+  uint8_t type_;        // 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 a direct index in the TracingMuxer::backends_ vector.
+// 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/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>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.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 ScatteredStreamWriter {
+ public:
+  class PERFETTO_EXPORT Delegate {
+   public:
+    virtual ~Delegate();
+    virtual ContiguousMemoryRange GetNewBuffer() = 0;
+  };
+
+  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 memcpy 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);
+    memcpy(write_ptr_, src, size);
+    write_ptr_ = end;
+  }
+
+  inline void WriteBytes(const uint8_t* src, size_t size) {
+    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;
+  }
+
+  // Resets the buffer boundaries and the write pointer to the given |range|.
+  // Subsequent WriteByte(s) will write into |range|.
+  void Reset(ContiguousMemoryRange range);
+
+  // 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_);
+  }
+
+  uint8_t* write_ptr() const { return write_ptr_; }
+
+  uint64_t written() const {
+    return written_previously_ +
+           static_cast<uint64_t>(write_ptr_ - cur_range_.begin);
+  }
+
+ private:
+  ScatteredStreamWriter(const ScatteredStreamWriter&) = delete;
+  ScatteredStreamWriter& operator=(const ScatteredStreamWriter&) = delete;
+
+  void Extend();
+
+  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 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.
+  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 (minus |size_already_written| below). This is the mechanism
+  // used by messages to backfill their corresponding size field in the parent
+  // message.
+  uint8_t* size_field() const { return size_field_; }
+  void set_size_field(uint8_t* size_field) { size_field_ = size_field; }
+
+  // This is to deal with case of backfilling the size of a root (non-nested)
+  // message which is split into multiple chunks. Upon finalization only the
+  // partial size that lies in the last chunk has to be backfilled.
+  void inc_size_already_written(uint32_t sz) { size_already_written_ += sz; }
+
+  Message* nested_message() { return nested_message_; }
+
+  bool is_finalized() const { return finalized_; }
+
+#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) {
+    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(!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_;
+
+  // See comment for inc_size_already_written().
+  uint32_t size_already_written_;
+
+  // When true, no more changes to the message are allowed. This is to DCHECK
+  // attempts of writing to a message which has been Finalize()-d.
+  bool finalized_;
+
+#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"
+
+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 MessageHandleBase {
+ public:
+  ~MessageHandleBase();
+
+  // Move-only type.
+  MessageHandleBase(MessageHandleBase&&) noexcept;
+  MessageHandleBase& operator=(MessageHandleBase&&);
+  explicit operator bool() const {
+#if PERFETTO_DCHECK_IS_ON()
+    PERFETTO_DCHECK(!message_ || generation_ == message_->generation_);
+#endif
+    return !!message_;
+  }
+
+ protected:
+  explicit MessageHandleBase(Message* = nullptr);
+  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&&);
+
+  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
+
+// The bare-minimum subset of the TraceWriter interface that is exposed as a
+// fully public API.
+// See comments in /include/perfetto/ext/tracing/core/trace_writer.h.
+class TraceWriterBase {
+ public:
+  virtual ~TraceWriterBase();
+
+  virtual protozero::MessageHandle<protos::pbzero::TracePacket>
+  NewTracePacket() = 0;
+
+  virtual void Flush(std::function<void()> callback = {}) = 0;
+  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/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.
+  bool trace_lambda_enabled = false;
+
+  // 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;
+
+  // A hash of the trace config used by this instance. This is used to
+  // de-duplicate instances for data sources with identical names (e.g., track
+  // event).
+  uint64_t config_hash = 0;
+
+  // 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 {
+  // 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");
+  }
+};
+
+// Per-DataSource-instance thread-local state.
+struct DataSourceInstanceThreadLocalState {
+  using IncrementalStatePointer = std::unique_ptr<void, void (*)(void*)>;
+
+  void Reset() {
+    trace_writer.reset();
+    incremental_state.reset();
+    backend_id = 0;
+    backend_connection_id = 0;
+    buffer_id = 0;
+    data_source_instance_id = 0;
+    incremental_state_generation = 0;
+    is_intercepted = false;
+  }
+
+  std::unique_ptr<TraceWriterBase> trace_writer;
+  IncrementalStatePointer incremental_state = {nullptr, [](void*) {}};
+  uint32_t incremental_state_generation;
+  TracingBackendId backend_id;
+  uint32_t backend_connection_id;
+  BufferId buffer_id;
+  uint64_t data_source_instance_id;
+  bool is_intercepted;
+};
+
+// 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::recursive_mutex* mtx, T* obj) : lock_(*mtx), 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 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 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 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::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 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;
+
+    // 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>();
+      return LockedHandle<InterceptorType>(
+          &internal_state->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 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_ = 0;
+
+  // 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_
+class PERFETTO_EXPORT 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 {
+    return PERFETTO_LIKELY(id < num_fields_) ? fields_[id] : 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 {
+    return RepeatedFieldIterator<T>(field_id, &fields_[num_fields_],
+                                    &fields_[size_], &fields_[field_id]);
+  }
+
+  // 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()) {
+      return PackedRepeatedFieldIterator<wire_type, cpp_type>(
+          field.data(), field.size(), parse_error_location);
+    } else {
+      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),
+        size_(num_fields),
+        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) * num_fields_);
+  }
+
+  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 fields without accounting repeated storage. This is equal to
+  // MAX_FIELD_ID + 1 (to account for the invalid 0th field).
+  // This value is always <= size_ (and hence <= capacity);
+  uint32_t num_fields_;
+
+  // Number of active |fields_| entries. This is initially equal to the highest
+  // number of fields for the message (num_fields_ == MAX_FIELD_ID + 1) and can
+  // grow up to |capacity_| in the case of repeated fields.
+  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_;
+};
+
+// 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,
+                              kCapacity,
+                              buffer,
+                              length) {
+    static_assert(MAX_FIELD_ID <= kMaxDecoderFieldId, "Field ordinal too high");
+    TypedProtoDecoderBase::ParseAllFields();
+  }
+
+  template <uint32_t FIELD_ID>
+  const Field& at() const {
+    static_assert(FIELD_ID <= MAX_FIELD_ID, "FIELD_ID > MAX_FIELD_ID");
+    return fields_[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:
+  // In the case of non-repeated fields, this constant defines the highest field
+  // id we are able to decode. This is to limit the on-stack storage.
+  // In the case of repeated fields, this constant defines the max number of
+  // repeated fields that we'll be able to store before falling back on the
+  // heap. Keep this value in sync with the one in protozero_generator.cc.
+  static constexpr size_t kMaxDecoderFieldId = 999;
+
+  // If we the message has no repeated fields we need at most N Field entries
+  // in the on-stack storage, where N is the highest field id.
+  // Otherwise we need some room to store repeated fields.
+  static constexpr size_t kCapacity =
+      1 + (HAS_NONPACKED_REPEATED_FIELDS ? kMaxDecoderFieldId : MAX_FIELD_ID);
+
+  Field on_stack_storage_[kCapacity];
+};
+
+}  // 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 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 SourceLocation;
+class TaskExecution;
+class TrackEvent_LegacyEvent;
+enum TrackEvent_LegacyEvent_FlowDirection : int32_t;
+enum TrackEvent_LegacyEvent_InstantEventScope : int32_t;
+enum TrackEvent_Type : int32_t;
+
+enum TrackEvent_Type : int32_t {
+  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,
+};
+
+const TrackEvent_Type TrackEvent_Type_MIN = TrackEvent_Type_TYPE_UNSPECIFIED;
+const TrackEvent_Type TrackEvent_Type_MAX = TrackEvent_Type_TYPE_COUNTER;
+
+enum TrackEvent_LegacyEvent_FlowDirection : int32_t {
+  TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED = 0,
+  TrackEvent_LegacyEvent_FlowDirection_FLOW_IN = 1,
+  TrackEvent_LegacyEvent_FlowDirection_FLOW_OUT = 2,
+  TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT = 3,
+};
+
+const TrackEvent_LegacyEvent_FlowDirection TrackEvent_LegacyEvent_FlowDirection_MIN = TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED;
+const TrackEvent_LegacyEvent_FlowDirection TrackEvent_LegacyEvent_FlowDirection_MAX = TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT;
+
+enum TrackEvent_LegacyEvent_InstantEventScope : int32_t {
+  TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED = 0,
+  TrackEvent_LegacyEvent_InstantEventScope_SCOPE_GLOBAL = 1,
+  TrackEvent_LegacyEvent_InstantEventScope_SCOPE_PROCESS = 2,
+  TrackEvent_LegacyEvent_InstantEventScope_SCOPE_THREAD = 3,
+};
+
+const TrackEvent_LegacyEvent_InstantEventScope TrackEvent_LegacyEvent_InstantEventScope_MIN = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED;
+const TrackEvent_LegacyEvent_InstantEventScope TrackEvent_LegacyEvent_InstantEventScope_MAX = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_THREAD;
+
+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,
+  };
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      EventName>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Iid kIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      EventCategory>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Iid kIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_TrackUuid =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEventDefaults>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrackUuid kTrackUuid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExtraCounterTrackUuids kExtraCounterTrackUuids() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExtraDoubleCounterTrackUuids kExtraDoubleCounterTrackUuids() { return {}; }
+  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=*/46, /*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() const { return at<36>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> flow_ids() const { return GetRepeated<uint64_t>(36); }
+  bool has_terminating_flow_ids() const { return at<42>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> terminating_flow_ids() const { return GetRepeated<uint64_t>(42); }
+  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_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,
+    kFlowIdsFieldNumber = 36,
+    kTerminatingFlowIdsFieldNumber = 42,
+    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,
+    kSourceLocationFieldNumber = 33,
+    kSourceLocationIidFieldNumber = 34,
+    kChromeMessagePumpFieldNumber = 35,
+    kChromeMojoEventInfoFieldNumber = 38,
+    kTimestampDeltaUsFieldNumber = 1,
+    kTimestampAbsoluteUsFieldNumber = 16,
+    kThreadTimeDeltaUsFieldNumber = 2,
+    kThreadTimeAbsoluteUsFieldNumber = 17,
+    kThreadInstructionCountDeltaFieldNumber = 8,
+    kThreadInstructionCountAbsoluteFieldNumber = 20,
+    kLegacyEventFieldNumber = 6,
+  };
+  using LegacyEvent = ::perfetto::protos::pbzero::TrackEvent_LegacyEvent;
+  using Type = ::perfetto::protos::pbzero::TrackEvent_Type;
+  static const Type TYPE_UNSPECIFIED = TrackEvent_Type_TYPE_UNSPECIFIED;
+  static const Type TYPE_SLICE_BEGIN = TrackEvent_Type_TYPE_SLICE_BEGIN;
+  static const Type TYPE_SLICE_END = TrackEvent_Type_TYPE_SLICE_END;
+  static const Type TYPE_INSTANT = TrackEvent_Type_TYPE_INSTANT;
+  static const Type TYPE_COUNTER = TrackEvent_Type_TYPE_COUNTER;
+
+  using FieldMetadata_CategoryIids =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CategoryIids kCategoryIids() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Categories kCategories() { return {}; }
+  void add_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Categories::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NameIid kNameIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrackUuid kTrackUuid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CounterValue kCounterValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DoubleCounterValue kDoubleCounterValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExtraCounterTrackUuids kExtraCounterTrackUuids() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExtraCounterValues kExtraCounterValues() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExtraDoubleCounterTrackUuids kExtraDoubleCounterTrackUuids() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExtraDoubleCounterValues kExtraDoubleCounterValues() { return {}; }
+  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_FlowIds =
+    ::protozero::proto_utils::FieldMetadata<
+      36,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FlowIds kFlowIds() { return {}; }
+  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::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TerminatingFlowIds =
+    ::protozero::proto_utils::FieldMetadata<
+      42,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TerminatingFlowIds kTerminatingFlowIds() { return {}; }
+  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::kUint64>
+        ::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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DebugAnnotations kDebugAnnotations() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TaskExecution kTaskExecution() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LogMessage kLogMessage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CcSchedulerState kCcSchedulerState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeUserEvent kChromeUserEvent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeKeyedService kChromeKeyedService() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeLegacyIpc kChromeLegacyIpc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeHistogramSample kChromeHistogramSample() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeLatencyInfo kChromeLatencyInfo() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeFrameReporter kChromeFrameReporter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeApplicationStateInfo kChromeApplicationStateInfo() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeRendererSchedulerState kChromeRendererSchedulerState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeWindowHandleEventInfo kChromeWindowHandleEventInfo() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeContentSettingsEventInfo kChromeContentSettingsEventInfo() { return {}; }
+  template <typename T = ChromeContentSettingsEventInfo> T* set_chrome_content_settings_event_info() {
+    return BeginNestedMessage<T>(43);
+  }
+
+
+  using FieldMetadata_SourceLocation =
+    ::protozero::proto_utils::FieldMetadata<
+      33,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SourceLocation,
+      TrackEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SourceLocation kSourceLocation() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SourceLocationIid kSourceLocationIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeMessagePump kChromeMessagePump() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeMojoEventInfo kChromeMojoEventInfo() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TimestampDeltaUs kTimestampDeltaUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TimestampAbsoluteUs kTimestampAbsoluteUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadTimeDeltaUs kThreadTimeDeltaUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadTimeAbsoluteUs kThreadTimeAbsoluteUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadInstructionCountDelta kThreadInstructionCountDelta() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadInstructionCountAbsolute kThreadInstructionCountAbsolute() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LegacyEvent kLegacyEvent() { return {}; }
+  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,
+  };
+  using FlowDirection = ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection;
+  using InstantEventScope = ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope;
+  static const FlowDirection FLOW_UNSPECIFIED = TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED;
+  static const FlowDirection FLOW_IN = TrackEvent_LegacyEvent_FlowDirection_FLOW_IN;
+  static const FlowDirection FLOW_OUT = TrackEvent_LegacyEvent_FlowDirection_FLOW_OUT;
+  static const FlowDirection FLOW_INOUT = TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT;
+  static const InstantEventScope SCOPE_UNSPECIFIED = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED;
+  static const InstantEventScope SCOPE_GLOBAL = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_GLOBAL;
+  static const InstantEventScope SCOPE_PROCESS = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_PROCESS;
+  static const InstantEventScope SCOPE_THREAD = TrackEvent_LegacyEvent_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NameIid kNameIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Phase kPhase() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DurationUs kDurationUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadDurationUs kThreadDurationUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadInstructionDelta kThreadInstructionDelta() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UnscopedId kUnscopedId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LocalId kLocalId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GlobalId kGlobalId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IdScope kIdScope() { return {}; }
+  void set_id_scope(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_IdScope::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UseAsyncTts kUseAsyncTts() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BindId kBindId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BindToEnclosing kBindToEnclosing() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FlowDirection kFlowDirection() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InstantEventScope kInstantEventScope() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PidOverride kPidOverride() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TidOverride kTidOverride() { return {}; }
+  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 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;
+  };
+
+  // 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 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 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_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 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 ChromeConfig;
+enum DataSourceConfig_SessionInitiator : 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 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,
+    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,
+    kPackagesListConfigFieldNumber = 109,
+    kPerfEventConfigFieldNumber = 111,
+    kVulkanMemoryConfigFieldNumber = 112,
+    kTrackEventConfigFieldNumber = 113,
+    kAndroidPolledStateConfigFieldNumber = 114,
+    kChromeConfigFieldNumber = 101,
+    kInterceptorConfigFieldNumber = 115,
+    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_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& 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); }
+
+  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(); }
+
+  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_{};
+  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 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]
+  ::protozero::CopyablePtr<ChromeConfig> chrome_config_;
+  ::protozero::CopyablePtr<InterceptorConfig> interceptor_config_;
+  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/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 DataSourceDescriptor : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kWillNotifyOnStopFieldNumber = 2,
+    kWillNotifyOnStartFieldNumber = 3,
+    kHandlesIncrementalStateClearFieldNumber = 4,
+    kGpuCounterDescriptorFieldNumber = 5,
+    kTrackEventDescriptorFieldNumber = 6,
+  };
+
+  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_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); }
+
+  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); }
+
+ private:
+  std::string name_{};
+  bool will_notify_on_stop_{};
+  bool will_notify_on_start_{};
+  bool handles_incremental_state_clear_{};
+  std::string gpu_counter_descriptor_;  // [lazy=true]
+  std::string track_event_descriptor_;  // [lazy=true]
+
+  // 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_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_TraceFilter;
+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 ChromeConfig;
+class TraceConfig_BufferConfig;
+enum TraceConfig_LockdownModeOperation : int;
+enum TraceConfig_CompressionType : int;
+enum TraceConfig_StatsdLogging : int;
+enum TraceConfig_TriggerConfig_TriggerMode : int;
+enum BuiltinClock : int;
+enum DataSourceConfig_SessionInitiator : 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_TriggerConfig_TriggerMode : int {
+  TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED = 0,
+  TraceConfig_TriggerConfig_TriggerMode_START_TRACING = 1,
+  TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING = 2,
+};
+enum TraceConfig_BufferConfig_FillPolicy : int {
+  TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED = 0,
+  TraceConfig_BufferConfig_FillPolicy_RING_BUFFER = 1,
+  TraceConfig_BufferConfig_FillPolicy_DISCARD = 2,
+};
+
+class PERFETTO_EXPORT 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 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,
+    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,
+    kIncidentReportConfigFieldNumber = 25,
+    kStatsdLoggingFieldNumber = 31,
+    kTraceUuidMsbFieldNumber = 27,
+    kTraceUuidLsbFieldNumber = 28,
+    kTraceFilterFieldNumber = 32,
+  };
+
+  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_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_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_[32]; }
+  const TraceConfig_TraceFilter& trace_filter() const { return *trace_filter_; }
+  TraceConfig_TraceFilter* mutable_trace_filter() { _has_field_.set(32); return trace_filter_.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 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_{};
+  ::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_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<33> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT TraceConfig_TraceFilter : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kBytecodeFieldNumber = 1,
+  };
+
+  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); }
+
+ private:
+  std::string bytecode_{};
+
+  // 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 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 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 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 TriggerMode_MIN = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
+  static constexpr auto TriggerMode_MAX = TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING;
+  enum FieldNumbers {
+    kTriggerModeFieldNumber = 1,
+    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); }
+
+  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_{};
+  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<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT 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 TraceConfig_GuardrailOverrides : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kMaxUploadPerDayBytesFieldNumber = 1,
+  };
+
+  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); }
+
+ private:
+  uint64_t max_upload_per_day_bytes_{};
+
+  // 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 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 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 TraceConfig_BuiltinDataSource : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDisableClockSnapshottingFieldNumber = 1,
+    kDisableTraceConfigFieldNumber = 2,
+    kDisableSystemInfoFieldNumber = 3,
+    kDisableServiceEventsFieldNumber = 4,
+    kPrimaryTraceClockFieldNumber = 5,
+    kSnapshotIntervalMsFieldNumber = 6,
+    kPreferSuspendClockForSnapshotFieldNumber = 7,
+  };
+
+  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); }
+
+ 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_{};
+
+  // 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 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 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,
+  };
+
+  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); }
+
+ private:
+  uint32_t size_kb_{};
+  TraceConfig_BufferConfig_FillPolicy fill_policy_{};
+
+  // 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_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"
+
+#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/internal/tracing_muxer.h
+// gen_amalgamated begin header: include/perfetto/tracing/internal/tracing_tls.h
+// gen_amalgamated begin header: 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_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"
+
+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 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 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();
+
+  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;
+};
+
+}  // 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;
+
+  // 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 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 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,
+                                  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;
+
+ 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_
+// 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 AndroidEnergyEstimationBreakdown;
+class AndroidLogPacket;
+class BatteryCounters;
+class ChromeBenchmarkMetadata;
+class ChromeEventBundle;
+class ChromeMetadataPacket;
+class ClockSnapshot;
+class CpuInfo;
+class DeobfuscationMapping;
+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 MemoryTrackerSnapshot;
+class ModuleSymbols;
+class PackagesList;
+class PerfSample;
+class PerfettoMetatrace;
+class PowerRails;
+class ProcessDescriptor;
+class ProcessStats;
+class ProcessTree;
+class ProfilePacket;
+class ProfiledFrameSymbols;
+class SmapsPacket;
+class StreamingAllocation;
+class StreamingFree;
+class StreamingProfilePacket;
+class SysStats;
+class SystemInfo;
+class TestEvent;
+class ThreadDescriptor;
+class TraceConfig;
+class TracePacketDefaults;
+class TraceStats;
+class TracingServiceEvent;
+class TrackDescriptor;
+class TrackEvent;
+class Trigger;
+class UiState;
+class VulkanApiEvent;
+class VulkanMemoryEvent;
+
+enum TracePacket_SequenceFlags : int32_t {
+  TracePacket_SequenceFlags_SEQ_UNSPECIFIED = 0,
+  TracePacket_SequenceFlags_SEQ_INCREMENTAL_STATE_CLEARED = 1,
+  TracePacket_SequenceFlags_SEQ_NEEDS_INCREMENTAL_STATE = 2,
+};
+
+const TracePacket_SequenceFlags TracePacket_SequenceFlags_MIN = TracePacket_SequenceFlags_SEQ_UNSPECIFIED;
+const TracePacket_SequenceFlags TracePacket_SequenceFlags_MAX = TracePacket_SequenceFlags_SEQ_NEEDS_INCREMENTAL_STATE;
+
+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_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_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_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_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(); }
+};
+
+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,
+    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,
+    kProfiledFrameSymbolsFieldNumber = 55,
+    kModuleSymbolsFieldNumber = 61,
+    kDeobfuscationMappingFieldNumber = 64,
+    kTrackDescriptorFieldNumber = 60,
+    kProcessDescriptorFieldNumber = 43,
+    kThreadDescriptorFieldNumber = 44,
+    kFtraceEventsFieldNumber = 1,
+    kSynchronizationMarkerFieldNumber = 36,
+    kCompressedPacketsFieldNumber = 50,
+    kExtensionDescriptorFieldNumber = 72,
+    kForTestingFieldNumber = 900,
+    kTrustedUidFieldNumber = 3,
+    kTrustedPacketSequenceIdFieldNumber = 10,
+    kInternedDataFieldNumber = 12,
+    kSequenceFlagsFieldNumber = 13,
+    kIncrementalStateClearedFieldNumber = 41,
+    kTracePacketDefaultsFieldNumber = 59,
+    kPreviousPacketDroppedFieldNumber = 42,
+  };
+  using SequenceFlags = ::perfetto::protos::pbzero::TracePacket_SequenceFlags;
+  static const SequenceFlags SEQ_UNSPECIFIED = TracePacket_SequenceFlags_SEQ_UNSPECIFIED;
+  static const SequenceFlags SEQ_INCREMENTAL_STATE_CLEARED = TracePacket_SequenceFlags_SEQ_INCREMENTAL_STATE_CLEARED;
+  static const SequenceFlags SEQ_NEEDS_INCREMENTAL_STATE = TracePacket_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Timestamp kTimestamp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TimestampClockId kTimestampClockId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessTree kProcessTree() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessStats kProcessStats() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InodeFileMap kInodeFileMap() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeEvents kChromeEvents() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClockSnapshot kClockSnapshot() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SysStats kSysStats() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrackEvent kTrackEvent() { return {}; }
+  template <typename T = TrackEvent> T* set_track_event() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_TraceConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      33,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig,
+      TracePacket>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceConfig kTraceConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FtraceStats kFtraceStats() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceStats kTraceStats() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProfilePacket kProfilePacket() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StreamingAllocation kStreamingAllocation() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StreamingFree kStreamingFree() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Battery kBattery() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PowerRails kPowerRails() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AndroidLog kAndroidLog() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SystemInfo kSystemInfo() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Trigger kTrigger() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PackagesList kPackagesList() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeBenchmarkMetadata kChromeBenchmarkMetadata() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PerfettoMetatrace kPerfettoMetatrace() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeMetadata kChromeMetadata() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuCounterEvent kGpuCounterEvent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuRenderStageEvent kGpuRenderStageEvent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StreamingProfilePacket kStreamingProfilePacket() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HeapGraph kHeapGraph() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GraphicsFrameEvent kGraphicsFrameEvent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VulkanMemoryEvent kVulkanMemoryEvent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuLog kGpuLog() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VulkanApiEvent kVulkanApiEvent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PerfSample kPerfSample() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuInfo kCpuInfo() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SmapsPacket kSmapsPacket() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ServiceEvent kServiceEvent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InitialDisplayState kInitialDisplayState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuMemTotalEvent kGpuMemTotalEvent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MemoryTrackerSnapshot kMemoryTrackerSnapshot() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FrameTimelineEvent kFrameTimelineEvent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AndroidEnergyEstimationBreakdown kAndroidEnergyEstimationBreakdown() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UiState kUiState() { return {}; }
+  template <typename T = UiState> T* set_ui_state() {
+    return BeginNestedMessage<T>(78);
+  }
+
+
+  using FieldMetadata_ProfiledFrameSymbols =
+    ::protozero::proto_utils::FieldMetadata<
+      55,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProfiledFrameSymbols,
+      TracePacket>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProfiledFrameSymbols kProfiledFrameSymbols() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ModuleSymbols kModuleSymbols() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DeobfuscationMapping kDeobfuscationMapping() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrackDescriptor kTrackDescriptor() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessDescriptor kProcessDescriptor() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadDescriptor kThreadDescriptor() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FtraceEvents kFtraceEvents() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SynchronizationMarker kSynchronizationMarker() { return {}; }
+  void set_synchronization_marker(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_SynchronizationMarker::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CompressedPackets kCompressedPackets() { return {}; }
+  void set_compressed_packets(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_CompressedPackets::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExtensionDescriptor kExtensionDescriptor() { return {}; }
+  template <typename T = ExtensionDescriptor> T* set_extension_descriptor() {
+    return BeginNestedMessage<T>(72);
+  }
+
+
+  using FieldMetadata_ForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      900,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TestEvent,
+      TracePacket>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ForTesting kForTesting() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrustedUid kTrustedUid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrustedPacketSequenceId kTrustedPacketSequenceId() { return {}; }
+  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_InternedData =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedData,
+      TracePacket>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InternedData kInternedData() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SequenceFlags kSequenceFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IncrementalStateCleared kIncrementalStateCleared() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TracePacketDefaults kTracePacketDefaults() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PreviousPacketDropped kPreviousPacketDropped() { return {}; }
+  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);
+  }
+};
+
+} // 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/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// 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/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/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"
+
+// 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)
+#define PERFETTO_COMPONENT_EXPORT
+#endif
+
+namespace perfetto {
+namespace internal {
+class TracingMuxerImpl;
+class TrackEventCategoryRegistry;
+template <typename, const internal::TrackEventCategoryRegistry*>
+class TrackEventDataSource;
+}  // namespace internal
+
+// 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 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;
+
+    // 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 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&);
+};
+
+struct DefaultDataSourceTraits {
+  // |IncrementalStateType| can optionally be used store custom per-sequence
+  // incremental data (e.g., interning tables). It should have a Clear() method
+  // for when incremental state needs to be cleared. See
+  // TraceContext::GetIncrementalState().
+  using IncrementalStateType = 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];
+    // The per-type TLS is either zero-initialized or must have been initialized
+    // for this specific data source type.
+    assert(!ds_tls->static_state ||
+           ds_tls->static_state->index == static_state->index);
+    return ds_tls;
+  }
+};
+
+// Templated base class meant to be derived by embedders to create a custom data
+// source. DataSourceType must be the type of the derived class itself, e.g.:
+// class MyDataSource : public DataSourceBase<MyDataSource> {...}.
+//
+// |DataSourceTraits| allows customizing the behavior of the data source. See
+// |DefaultDataSourceTraits|.
+template <typename DataSourceType,
+          typename DataSourceTraits = DefaultDataSourceTraits>
+class DataSource : public DataSourceBase {
+  struct DefaultTracePointTraits;
+
+ 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;
+
+  // 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();
+    }
+
+    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<DataSourceType> GetDataSourceLocked() {
+      auto* internal_state = static_state_.TryGet(instance_index_);
+      if (!internal_state)
+        return LockedHandle<DataSourceType>();
+      return LockedHandle<DataSourceType>(
+          &internal_state->lock,
+          static_cast<DataSourceType*>(internal_state->data_source.get()));
+    }
+
+    typename DataSourceTraits::IncrementalStateType* GetIncrementalState() {
+      // 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_);
+      }
+      return reinterpret_cast<typename DataSourceTraits::IncrementalStateType*>(
+          tls_inst_->incremental_state.get());
+    }
+
+   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 |static_state_| 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.
+  //
+  // TODO(primiano): all the stuff below should be outlined from the trace
+  // point. Or at least we should have some compile-time traits like
+  // kOptimizeBinarySize / kOptimizeTracingLatency.
+  template <typename Traits = DefaultTracePointTraits, typename Lambda>
+  static void TraceWithInstances(
+      uint32_t instances,
+      Lambda tracing_fn,
+      typename Traits::TracePointData trace_point_data = {}) {
+    PERFETTO_DCHECK(instances);
+    constexpr auto kMaxDataSourceInstances = internal::kMaxDataSourceInstances;
+
+    // See tracing_muxer.h for the structure of the TLS.
+    auto* tracing_impl = internal::TracingMuxer::Get();
+    if (PERFETTO_UNLIKELY(!tls_state_))
+      tls_state_ = GetOrCreateDataSourceTLS(&static_state_);
+
+    // Avoid re-entering the trace point recursively.
+    if (PERFETTO_UNLIKELY(tls_state_->root_tls->is_in_trace_point))
+      return;
+    internal::ScopedReentrancyAnnotator scoped_annotator(*tls_state_->root_tls);
+
+    // 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();
+    }
+
+    for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
+      internal::DataSourceState* instance_state =
+          static_state_.TryGetCached(instances, 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[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.
+        instances = Traits::GetActiveInstances(trace_point_data)
+                        ->load(std::memory_order_acquire);
+        instance_state = static_state_.TryGetCached(instances, i);
+        if (!instance_state || !instance_state->trace_lambda_enabled)
+          continue;
+        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.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(
+            &static_state_, i, instance_state,
+            DataSourceType::kBufferExhaustedPolicy);
+        CreateIncrementalState(&tls_inst);
+
+        // Even in the case of out-of-IDs, SharedMemoryArbiterImpl returns a
+        // NullTraceWriter. The returned pointer should never be null.
+        assert(tls_inst.trace_writer);
+      }
+
+      tracing_fn(TraceContext(&tls_inst, i));
+    }
+  }
+
+  // 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)static_state_;
+    (void)tls_state_;
+
+    auto factory = [constructor_args...]() {
+      return std::unique_ptr<DataSourceBase>(
+          new DataSourceType(constructor_args...));
+    };
+    auto* tracing_impl = internal::TracingMuxer::Get();
+    return tracing_impl->RegisterDataSource(descriptor, factory,
+                                            &static_state_);
+  }
+
+ private:
+  // 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 &static_state_.valid_instances;
+    }
+  };
+
+  // Create the user provided incremental state in the given thread-local
+  // storage. Note: The second parameter here is used to specialize the case
+  // where there is no incremental state type.
+  template <typename T>
+  static void CreateIncrementalStateImpl(
+      internal::DataSourceInstanceThreadLocalState* tls_inst,
+      const T*) {
+    PERFETTO_DCHECK(!tls_inst->incremental_state);
+    tls_inst->incremental_state_generation =
+        static_state_.incremental_state_generation.load(
+            std::memory_order_relaxed);
+    tls_inst->incremental_state =
+        internal::DataSourceInstanceThreadLocalState::IncrementalStatePointer(
+            reinterpret_cast<void*>(new T()),
+            [](void* p) { delete reinterpret_cast<T*>(p); });
+  }
+
+  static void CreateIncrementalStateImpl(
+      internal::DataSourceInstanceThreadLocalState*,
+      const void*) {}
+
+  static void CreateIncrementalState(
+      internal::DataSourceInstanceThreadLocalState* tls_inst) {
+    CreateIncrementalStateImpl(
+        tls_inst,
+        static_cast<typename DataSourceTraits::IncrementalStateType*>(nullptr));
+  }
+
+  // Note that the returned object is one per-thread per-data-source-type, NOT
+  // per data-source *instance*.
+  static internal::DataSourceThreadLocalState* GetOrCreateDataSourceTLS(
+      internal::DataSourceStaticState* static_state) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_IOS)
+    PERFETTO_FATAL("Data source TLS not supported on iOS, see b/158814068");
+#endif
+    auto* tracing_impl = internal::TracingMuxer::Get();
+    internal::TracingTLS* root_tls = tracing_impl->GetOrCreateTracingTLS();
+    internal::DataSourceThreadLocalState* ds_tls =
+        DataSourceTraits::GetDataSourceTLS(static_state, root_tls);
+    // We keep re-initializing as the initialization is idempotent and not worth
+    // the code for extra checks.
+    ds_tls->static_state = static_state;
+    assert(!ds_tls->root_tls || ds_tls->root_tls == root_tls);
+    ds_tls->root_tls = root_tls;
+    return ds_tls;
+  }
+
+  // Static state. Accessed by the static Trace() method fastpaths.
+  static internal::DataSourceStaticState static_state_;
+
+  // 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 PERFETTO_THREAD_LOCAL internal::DataSourceThreadLocalState* tls_state_;
+};
+
+// static
+template <typename T, typename D>
+internal::DataSourceStaticState DataSource<T, D>::static_state_;
+// static
+template <typename T, typename D>
+PERFETTO_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(...)              \
+  template <>                                                         \
+  PERFETTO_COMPONENT_EXPORT perfetto::internal::DataSourceStaticState \
+      perfetto::DataSource<__VA_ARGS__>::static_state_;               \
+  template <>                                                         \
+  PERFETTO_COMPONENT_EXPORT PERFETTO_THREAD_LOCAL                     \
+      perfetto::internal::DataSourceThreadLocalState*                 \
+          perfetto::DataSource<__VA_ARGS__>::tls_state_
+
+// MSVC has a bug where explicit template member specialization declarations
+// can't have thread_local as the storage class specifier. The generated code
+// seems correct without the specifier, so drop it until the bug gets fixed.
+// See https://developercommunity2.visualstudio.com/t/Unable-to-specialize-
+// static-thread_local/1302689.
+#if PERFETTO_BUILDFLAG(PERFETTO_COMPILER_MSVC)
+#define PERFETTO_TEMPLATE_THREAD_LOCAL
+#else
+#define PERFETTO_TEMPLATE_THREAD_LOCAL PERFETTO_THREAD_LOCAL
+#endif
+
+// 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.
+//
+// Note: if MSVC fails with a C2086 (redefinition) error here, use the
+// permissive- flag to enable standards-compliant mode. See
+// https://developercommunity.visualstudio.com/content/problem/319447/
+// explicit-specialization-of-static-data-member-inco.html.
+#define PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(...)               \
+  template <>                                                         \
+  PERFETTO_COMPONENT_EXPORT perfetto::internal::DataSourceStaticState \
+      perfetto::DataSource<__VA_ARGS__>::static_state_{};             \
+  template <>                                                         \
+  PERFETTO_COMPONENT_EXPORT PERFETTO_TEMPLATE_THREAD_LOCAL            \
+      perfetto::internal::DataSourceThreadLocalState*                 \
+          perfetto::DataSource<__VA_ARGS__>::tls_state_ = nullptr
+
+#endif  // INCLUDE_PERFETTO_TRACING_DATA_SOURCE_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
+/*
+ * 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 <memory>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.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;
+
+class PERFETTO_EXPORT TracingBackend {
+ public:
+  virtual ~TracingBackend();
+
+  // 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;
+  };
+
+  virtual std::unique_ptr<ProducerEndpoint> ConnectProducer(
+      const ConnectProducerArgs&) = 0;
+
+  // 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;
+};
+
+}  // 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 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
+/*
+ * 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/tracing_backend.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}
+
+class Producer;
+
+// A built-in implementation of TracingBackend that connects 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). It allows 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 {
+class PERFETTO_EXPORT SystemTracingBackend : 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:
+  SystemTracingBackend();
+};
+
+}  // 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 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 <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 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] 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;
+
+ protected:
+  friend class Tracing;
+  friend class internal::TracingMuxerImpl;
+
+  // Used only by the DCHECK in tracing.cc, to check that the config is the
+  // same in case of re-initialization.
+  bool operator==(const TracingInitArgs& other) const {
+    return std::tie(backends, custom_backend, platform, shmem_size_hint_kb,
+                    shmem_page_size_hint_kb, in_process_backend_factory_,
+                    system_backend_factory_, dcheck_is_on_) ==
+           std::tie(other.backends, other.custom_backend, other.platform,
+                    other.shmem_size_hint_kb, other.shmem_page_size_hint_kb,
+                    other.in_process_backend_factory_,
+                    other.system_backend_factory_, other.dcheck_is_on_);
+  }
+
+  using BackendFactoryFunction = TracingBackend* (*)();
+  BackendFactoryFunction in_process_backend_factory_ = nullptr;
+  BackendFactoryFunction system_backend_factory_ = nullptr;
+  bool dcheck_is_on_ = PERFETTO_DCHECK_IS_ON();
+};
+
+// The entry-point for using perfetto.
+class PERFETTO_EXPORT Tracing {
+ public:
+  // Initializes Perfetto with the given backends in the calling process and/or
+  // with a user-provided backend. No-op if called more than once.
+  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_backend_factory_ =
+          &internal::SystemTracingBackend::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.
+  // For the moment this can be used only when initializing tracing in
+  // kInProcess mode. For the system mode use the 'bin/perfetto' cmdline client.
+  static std::unique_ptr<TracingSession> NewTrace(
+      BackendType = kUnspecifiedBackend);
+
+ private:
+  static void InitializeInternal(const TracingInitArgs&);
+
+  Tracing() = delete;
+};
+
+class PERFETTO_EXPORT 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();
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACING_H_
+// gen_amalgamated begin header: include/perfetto/tracing/track_event.h
+// gen_amalgamated begin header: include/perfetto/base/time.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 <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);
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+TimeNanos GetWallTimeNs();
+TimeNanos GetThreadCPUTimeNs();
+
+// 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_time_factor = []() -> uint64_t {
+    mach_timebase_info_data_t timebase_info;
+    mach_timebase_info(&timebase_info);
+    return timebase_info.numer / timebase_info.denom;
+  };
+
+  static uint64_t monotonic_timebase_factor = init_time_factor();
+  return TimeNanos(mach_absolute_time() * monotonic_timebase_factor);
+}
+
+// TODO: Clock that counts time during suspend is not implemented on Mac.
+inline TimeNanos GetBootTimeNs() {
+  return GetWallTimeNs();
+}
+
+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);
+}
+
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
+
+inline TimeNanos GetWallTimeNs() {
+  return TimeNanos(static_cast<uint64_t>(emscripten_get_now()) * 1000000);
+}
+
+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 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 GetThreadCPUTimeNs() {
+  return GetTimeInternalNs(CLOCK_THREAD_CPUTIME_ID);
+}
+#endif
+
+inline TimeSeconds GetBootTimeS() {
+  return std::chrono::duration_cast<TimeSeconds>(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);
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_TIME_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 <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 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_.back().entries > 0);
+    PERFETTO_DCHECK(&blocks_.back().storage[blocks_.back().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_.back();
+    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::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 ScatteredHeapBuffer
+    : public protozero::ScatteredStreamWriter::Delegate {
+ public:
+  class PERFETTO_EXPORT 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 T>
+void WriteIntoTracedValue(TracedValue context, T&& value);
+
+template <typename T, class = void>
+struct TraceFormatTraits;
+
+// Write support checker to allow it to be used when matching.
+//
+// Intended to be used for types like smart pointers, who should support
+// AsTracedValueInto only iff their inner type supports being written into
+// a TracedValue.
+//
+// template <typename T>
+// class SmartPtr {
+//   ...
+//
+//   typename check_traced_value_support<T, void>::value
+//   AsTracedValueInto(perfetto::TracedValue context) const {
+//      WriteIntoTracedValue(std::move(context), *ptr_);
+//   }
+// };
+template <typename T, typename ResultType = void, class = void>
+struct check_traced_value_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;
+enum DebugAnnotation_NestedValue_NestedType : int32_t;
+
+enum DebugAnnotation_NestedValue_NestedType : int32_t {
+  DebugAnnotation_NestedValue_NestedType_UNSPECIFIED = 0,
+  DebugAnnotation_NestedValue_NestedType_DICT = 1,
+  DebugAnnotation_NestedValue_NestedType_ARRAY = 2,
+};
+
+const DebugAnnotation_NestedValue_NestedType DebugAnnotation_NestedValue_NestedType_MIN = DebugAnnotation_NestedValue_NestedType_UNSPECIFIED;
+const DebugAnnotation_NestedValue_NestedType DebugAnnotation_NestedValue_NestedType_MAX = DebugAnnotation_NestedValue_NestedType_ARRAY;
+
+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,
+  };
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DebugAnnotationName>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Iid kIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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=*/12, /*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_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_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_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,
+    kStringValueFieldNumber = 6,
+    kPointerValueFieldNumber = 7,
+    kNestedValueFieldNumber = 8,
+    kLegacyJsonValueFieldNumber = 9,
+    kDictEntriesFieldNumber = 11,
+    kArrayValuesFieldNumber = 12,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NameIid kNameIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BoolValue kBoolValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UintValue kUintValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IntValue kIntValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DoubleValue kDoubleValue() { return {}; }
+  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,
+      DebugAnnotation>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StringValue kStringValue() { return {}; }
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, 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,
+      DebugAnnotation>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PointerValue kPointerValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NestedValue kNestedValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LegacyJsonValue kLegacyJsonValue() { return {}; }
+  void set_legacy_json_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LegacyJsonValue::kFieldId, data, 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_DictEntries =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotation,
+      DebugAnnotation>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DictEntries kDictEntries() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ArrayValues kArrayValues() { return {}; }
+  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,
+  };
+  using NestedType = ::perfetto::protos::pbzero::DebugAnnotation_NestedValue_NestedType;
+  static const NestedType UNSPECIFIED = DebugAnnotation_NestedValue_NestedType_UNSPECIFIED;
+  static const NestedType DICT = DebugAnnotation_NestedValue_NestedType_DICT;
+  static const NestedType ARRAY = DebugAnnotation_NestedValue_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NestedType kNestedType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DictKeys kDictKeys() { return {}; }
+  void add_dict_keys(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DictKeys::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DictValues kDictValues() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ArrayValues kArrayValues() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IntValue kIntValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DoubleValue kDoubleValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BoolValue kBoolValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StringValue kStringValue() { return {}; }
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, 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 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 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() {}
+
+  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"
+
+#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 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;
+};
+
+namespace internal {
+
+// Ensure that |string| is a static constant string.
+//
+// If you get a compiler failure here, you are most likely trying to use
+// TRACE_EVENT with a dynamic event name. There are two ways to fix this:
+//
+// 1) If the event name is actually dynamic (e.g., std::string), write it into
+//    the event manually:
+//
+//      TRACE_EVENT("category", nullptr, [&](perfetto::EventContext ctx) {
+//        ctx.event()->set_name(dynamic_name);
+//      });
+//
+// 2) If the name is static, but the pointer is computed at runtime, wrap it
+//    with perfetto::StaticString:
+//
+//      TRACE_EVENT("category", perfetto::StaticString{name});
+//
+//    DANGER: Using perfetto::StaticString with strings whose contents change
+//            dynamically can cause silent trace data corruption.
+//
+constexpr const char* GetStaticString(StaticString string) {
+  return string.value;
+}
+
+}  // namespace internal
+
+// A explicit wrapper for marking strings as dynamic to ensure that perfetto
+// doesn't try to cache the pointer value.
+class PERFETTO_EXPORT DynamicString {
+ public:
+  explicit DynamicString(const std::string& str)
+      : value(str.data()), length(str.length()) {}
+  explicit DynamicString(const char* str) : value(str), length(strlen(str)) {}
+  DynamicString(const char* str, size_t len) : value(str), length(len) {}
+
+  const char* value;
+  size_t length;
+};
+
+}  // 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 <type_traits>
+#include <utility>
+
+namespace perfetto {
+
+namespace protos {
+namespace pbzero {
+class DebugAnnotation;
+}
+}  // namespace protos
+
+class DebugAnnotation;
+
+// 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 definiting 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 {
+PERFETTO_EXPORT TracedValue
+CreateTracedValueFromProto(protos::pbzero::DebugAnnotation*);
+}
+
+class PERFETTO_EXPORT TracedValue {
+ public:
+  TracedValue(const TracedValue&) = delete;
+  TracedValue& operator=(const TracedValue&) = delete;
+  TracedValue& operator=(TracedValue&&) = delete;
+  TracedValue(TracedValue&&) = default;
+  ~TracedValue() = default;
+
+  // 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 WritePointer(const void* value) &&;
+
+  // 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, it's 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*);
+
+  static TracedValue CreateFromProto(protos::pbzero::DebugAnnotation*);
+
+  inline explicit TracedValue(protos::pbzero::DebugAnnotation* context,
+                              internal::CheckedScope* parent_scope)
+      : context_(context), checked_scope_(parent_scope) {}
+
+  // 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 context_ = nullptr;
+
+  internal::CheckedScope checked_scope_;
+};
+
+class PERFETTO_EXPORT TracedArray {
+ public:
+  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 explicit TracedArray(protos::pbzero::DebugAnnotation* context,
+                              internal::CheckedScope* parent_scope)
+      : context_(context), checked_scope_(parent_scope) {}
+
+  protos::pbzero::DebugAnnotation* context_;
+
+  internal::CheckedScope checked_scope_;
+};
+
+class PERFETTO_EXPORT TracedDictionary {
+ public:
+  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 explicit TracedDictionary(
+      MessageType* message,
+      protozero::proto_utils::internal::FieldMetadataHelper<FieldMetadata>,
+      internal::CheckedScope* parent_scope)
+      : message_(message),
+        field_id_(FieldMetadata::kFieldId),
+        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_;
+
+  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);
+  }
+};
+
+// 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 (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());
+  }
+};
+
+// 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);
+  }
+};
+
+// Specialisation for nullptr.
+template <>
+struct TraceFormatTraits<std::nullptr_t> {
+  inline static void WriteIntoTrace(TracedValue context, std::nullptr_t) {
+    std::move(context).WritePointer(nullptr);
+  }
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACED_VALUE_H_
+// gen_amalgamated begin header: include/perfetto/tracing/track.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)
+#include <Windows.h>
+#include <processthreadsapi.h>
+#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"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#include <processthreadsapi.h>
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+#include <zircon/process.h>
+#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_handle_t;
+inline PlatformThreadId GetThreadId() {
+  return zx_thread_self();
+}
+#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/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.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 {
+
+enum CounterDescriptor_BuiltinCounterType : int32_t;
+enum CounterDescriptor_Unit : int32_t;
+
+enum CounterDescriptor_BuiltinCounterType : int32_t {
+  CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED = 0,
+  CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_TIME_NS = 1,
+  CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT = 2,
+};
+
+const CounterDescriptor_BuiltinCounterType CounterDescriptor_BuiltinCounterType_MIN = CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED;
+const CounterDescriptor_BuiltinCounterType CounterDescriptor_BuiltinCounterType_MAX = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT;
+
+enum CounterDescriptor_Unit : int32_t {
+  CounterDescriptor_Unit_UNIT_UNSPECIFIED = 0,
+  CounterDescriptor_Unit_UNIT_TIME_NS = 1,
+  CounterDescriptor_Unit_UNIT_COUNT = 2,
+  CounterDescriptor_Unit_UNIT_SIZE_BYTES = 3,
+};
+
+const CounterDescriptor_Unit CounterDescriptor_Unit_MIN = CounterDescriptor_Unit_UNIT_UNSPECIFIED;
+const CounterDescriptor_Unit CounterDescriptor_Unit_MAX = CounterDescriptor_Unit_UNIT_SIZE_BYTES;
+
+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,
+  };
+  using BuiltinCounterType = ::perfetto::protos::pbzero::CounterDescriptor_BuiltinCounterType;
+  using Unit = ::perfetto::protos::pbzero::CounterDescriptor_Unit;
+  static const BuiltinCounterType COUNTER_UNSPECIFIED = CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED;
+  static const BuiltinCounterType COUNTER_THREAD_TIME_NS = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_TIME_NS;
+  static const BuiltinCounterType COUNTER_THREAD_INSTRUCTION_COUNT = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT;
+  static const Unit UNIT_UNSPECIFIED = CounterDescriptor_Unit_UNIT_UNSPECIFIED;
+  static const Unit UNIT_TIME_NS = CounterDescriptor_Unit_UNIT_TIME_NS;
+  static const Unit UNIT_COUNT = CounterDescriptor_Unit_UNIT_COUNT;
+  static const Unit UNIT_SIZE_BYTES = CounterDescriptor_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Categories kCategories() { return {}; }
+  void add_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Categories::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Unit kUnit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UnitName kUnitName() { return {}; }
+  void set_unit_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_UnitName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UnitMultiplier kUnitMultiplier() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IsIncremental kIsIncremental() { return {}; }
+  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 TrackDescriptor : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kUuidFieldNumber = 1,
+    kParentUuidFieldNumber = 5,
+    kNameFieldNumber = 2,
+    kProcessFieldNumber = 3,
+    kChromeProcessFieldNumber = 6,
+    kThreadFieldNumber = 4,
+    kChromeThreadFieldNumber = 7,
+    kCounterFieldNumber = 8,
+  };
+
+  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(); }
+
+ 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_;
+
+  // 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_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=*/8, /*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(); }
+};
+
+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,
+  };
+
+  using FieldMetadata_Uuid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackDescriptor>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Uuid kUuid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ParentUuid kParentUuid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Process kProcess() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeProcess kChromeProcess() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Thread kThread() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeThread kChromeThread() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Counter kCounter() { return {}; }
+  template <typename T = CounterDescriptor> T* set_counter() {
+    return BeginNestedMessage<T>(8);
+  }
+
+};
+
+} // 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 "protos/perfetto/trace/trace_packet.pbzero.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;
+}
+
+// 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 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);
+  }
+
+ 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;
+  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 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(base::GetProcessId()) {}
+};
+
+// A thread track is associated with a specific thread of execution. Currently
+// only threads in the current process can be referenced.
+struct PERFETTO_EXPORT ThreadTrack : public Track {
+  const base::PlatformProcessId pid;
+  const base::PlatformThreadId tid;
+
+  static ThreadTrack Current() { return ThreadTrack(base::GetThreadId()); }
+
+  // Represents a thread in the current process.
+  static ThreadTrack ForThread(base::PlatformThreadId tid_) {
+    return ThreadTrack(tid_);
+  }
+
+  void Serialize(protos::pbzero::TrackDescriptor*) const;
+  protos::gen::TrackDescriptor Serialize() const;
+
+ private:
+  explicit ThreadTrack(base::PlatformThreadId tid_)
+      : Track(MakeThreadTrack(tid_)),
+        pid(ProcessTrack::Current().pid),
+        tid(tid_) {}
+};
+
+// 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 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;
+
+  // |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_);
+  }
+
+  constexpr CounterTrack set_unit_name(const char* unit_name) const {
+    return CounterTrack(uuid, parent_uuid, name_, category_, unit_, unit_name,
+                        unit_multiplier_, is_incremental_);
+  }
+
+  constexpr CounterTrack set_unit_multiplier(int64_t unit_multiplier) const {
+    return CounterTrack(uuid, parent_uuid, name_, category_, unit_, unit_name_,
+                        unit_multiplier, is_incremental_);
+  }
+
+  constexpr CounterTrack set_category(const char* category) const {
+    return CounterTrack(uuid, parent_uuid, name_, category, unit_, unit_name_,
+                        unit_multiplier_, 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)
+      : Track(uuid_, parent_uuid_),
+        name_(name),
+        category_(category),
+        unit_(unit),
+        unit_name_(unit_name),
+        unit_multiplier_(unit_multiplier),
+        is_incremental_(is_incremental) {}
+
+  // TODO(skyostil): Expose incremental counters once we decide how to manage
+  // their incremental state.
+  constexpr CounterTrack set_is_incremental(bool is_incremental = true) const {
+    return CounterTrack(uuid, parent_uuid, name_, category_, unit_, unit_name_,
+                        unit_multiplier_, is_incremental);
+  }
+
+  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;
+  bool is_incremental_ = false;
+};
+
+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 once Chromium no longer calls
+// TrackRegistry::InitializeInstance() directly.
+class PERFETTO_EXPORT TrackRegistry {
+ public:
+  using SerializedTrackDescriptor = std::string;
+
+  TrackRegistry();
+  ~TrackRegistry();
+
+  static void InitializeInstance();
+  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,
+};
+
+const BuiltinClock BuiltinClock_MIN = BUILTIN_CLOCK_UNKNOWN;
+const BuiltinClock BuiltinClock_MAX = BUILTIN_CLOCK_MAX_ID;
+
+} // 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 EventCategory;
+class EventName;
+class Frame;
+class HistogramName;
+class InternedGpuRenderStageSpecification;
+class InternedGraphicsContext;
+class InternedString;
+class LogMessageBody;
+class Mapping;
+class ProfiledFrameSymbols;
+class SourceLocation;
+
+class InternedData_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/26, /*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_source_locations() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> source_locations() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  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); }
+};
+
+class InternedData : public ::protozero::Message {
+ public:
+  using Decoder = InternedData_Decoder;
+  enum : int32_t {
+    kEventCategoriesFieldNumber = 1,
+    kEventNamesFieldNumber = 2,
+    kDebugAnnotationNamesFieldNumber = 3,
+    kSourceLocationsFieldNumber = 4,
+    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,
+  };
+
+  using FieldMetadata_EventCategories =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EventCategory,
+      InternedData>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EventCategories kEventCategories() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EventNames kEventNames() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DebugAnnotationNames kDebugAnnotationNames() { return {}; }
+  template <typename T = DebugAnnotationName> T* add_debug_annotation_names() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_SourceLocations =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SourceLocation,
+      InternedData>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SourceLocations kSourceLocations() { return {}; }
+  template <typename T = SourceLocation> T* add_source_locations() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_LogMessageBody =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LogMessageBody,
+      InternedData>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LogMessageBody kLogMessageBody() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HistogramNames kHistogramNames() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BuildIds kBuildIds() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MappingPaths kMappingPaths() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SourcePaths kSourcePaths() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FunctionNames kFunctionNames() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProfiledFrameSymbols kProfiledFrameSymbols() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mappings kMappings() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Frames kFrames() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Callstacks kCallstacks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VulkanMemoryKeys kVulkanMemoryKeys() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GraphicsContexts kGraphicsContexts() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuSpecifications kGpuSpecifications() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_KernelSymbols kKernelSymbols() { return {}; }
+  template <typename T = InternedString> T* add_kernel_symbols() {
+    return BeginNestedMessage<T>(26);
+  }
+
+};
+
+} // 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 {
+  protos::pbzero::BuiltinClock clock_id;
+  uint64_t nanoseconds;
+};
+
+class EventContext;
+class TrackEventSessionObserver;
+struct Category;
+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 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&);
+};
+
+namespace internal {
+class TrackEventCategoryRegistry;
+
+class PERFETTO_EXPORT 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 TrackEventIncrementalState {
+  static constexpr size_t kMaxInternedDataFields = 32;
+
+  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 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 TrackEventInternal {
+ public:
+  static bool Initialize(
+      const TrackEventCategoryRegistry&,
+      bool (*register_data_source)(const DataSourceDescriptor&));
+
+  static bool AddSessionObserver(TrackEventSessionObserver*);
+  static void RemoveSessionObserver(TrackEventSessionObserver*);
+
+  static void EnableTracing(const TrackEventCategoryRegistry& registry,
+                            const protos::gen::TrackEventConfig& config,
+                            const DataSourceBase::SetupArgs&);
+  static void OnStart(const DataSourceBase::StartArgs&);
+  static void DisableTracing(const TrackEventCategoryRegistry& registry,
+                             const DataSourceBase::StopArgs&);
+  static bool IsCategoryEnabled(const TrackEventCategoryRegistry& registry,
+                                const protos::gen::TrackEventConfig& config,
+                                const Category& category);
+
+  static perfetto::EventContext WriteEvent(
+      TraceWriterBase*,
+      TrackEventIncrementalState*,
+      const Category* category,
+      const char* name,
+      perfetto::protos::pbzero::TrackEvent::Type,
+      TraceTimestamp timestamp = {GetClockId(), GetTimeNs()});
+
+  static void ResetIncrementalState(TraceWriterBase*, TraceTimestamp);
+
+  template <typename T>
+  static void AddDebugAnnotation(perfetto::EventContext* event_ctx,
+                                 const char* name,
+                                 T&& value) {
+    auto annotation = AddDebugAnnotation(event_ctx, name);
+    WriteIntoTracedValue(internal::CreateTracedValueFromProto(annotation),
+                         std::forward<T>(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) {
+    auto it_and_inserted = incr_state->seen_tracks.insert(track.uuid);
+    if (PERFETTO_LIKELY(!it_and_inserted.second))
+      return;
+    WriteTrackDescriptor(track, trace_writer);
+  }
+
+  // Unconditionally write a track descriptor into the trace.
+  template <typename TrackType>
+  static void WriteTrackDescriptor(const TrackType& track,
+                                   TraceWriterBase* trace_writer) {
+    TrackRegistry::Get()->SerializeTrack(
+        track, NewTracePacket(trace_writer, {GetClockId(), GetTimeNs()}));
+  }
+
+  // Get the current time in nanoseconds in the trace clock timebase.
+  static uint64_t GetTimeNs();
+
+  // Get the clock used by GetTimeNs().
+  static constexpr protos::pbzero::BuiltinClock GetClockId() {
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    return protos::pbzero::BUILTIN_CLOCK_BOOTTIME;
+#else
+    return protos::pbzero::BUILTIN_CLOCK_MONOTONIC;
+#endif
+  }
+
+  static int GetSessionCount();
+
+  // Represents the default track for the calling thread.
+  static const Track kDefaultTrack;
+
+ private:
+  static protozero::MessageHandle<protos::pbzero::TracePacket> NewTracePacket(
+      TraceWriterBase*,
+      TraceTimestamp,
+      uint32_t seq_flags =
+          protos::pbzero::TracePacket::SEQ_NEEDS_INCREMENTAL_STATE);
+  static protos::pbzero::DebugAnnotation* AddDebugAnnotation(
+      perfetto::EventContext*,
+      const char* name);
+
+  static std::atomic<int> session_count_;
+};
+
+}  // 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;
+
+// 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:
+  TracedProto(const TracedProto&) = delete;
+  TracedProto& operator=(const TracedProto&) = delete;
+  TracedProto& operator=(TracedProto&&) = delete;
+  TracedProto(TracedProto&&) = default;
+  ~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, nullptr);
+  }
+
+  // Write a nested message into a field according to the provided metadata.
+  template <typename FieldMetadata>
+  TracedProto<typename FieldMetadata::cpp_field_type> WriteNestedMessage() {
+    static_assert(std::is_base_of<MessageType,
+                                  typename FieldMetadata::message_type>::value,
+                  "Field should belong to the current message");
+    return TracedProto<typename FieldMetadata::cpp_field_type>(
+        message_->template BeginNestedMessage<
+            typename FieldMetadata::cpp_field_type>(FieldMetadata::kFieldId),
+        context_);
+  }
+
+  template <typename FieldMetadata>
+  TracedProto<typename FieldMetadata::cpp_field_type> WriteNestedMessage(
+      protozero::proto_utils::internal::FieldMetadataHelper<FieldMetadata>) {
+    return WriteNestedMessage<FieldMetadata>();
+  }
+
+ private:
+  friend class EventContext;
+  // 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(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_;
+};
+
+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) {
+    // TODO(altimin): support TraceFormatTraits here.
+    value.WriteIntoTrace(context.template WriteNestedMessage<FieldMetadata>());
+  }
+};
+
+// 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) {
+    // TODO(altimin): support TraceFormatTraits here.
+    for (auto&& item : value) {
+      item.WriteIntoTrace(context.template WriteNestedMessage<FieldMetadata>());
+    }
+  }
+};
+
+// 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(std::move(context),
+                                               std::forward<ValueType>(value));
+  }
+};
+
+}  // namespace internal
+
+template <typename MessageType, typename FieldMetadataType, typename ValueType>
+void WriteIntoTracedProto(
+    TracedProto<MessageType> message,
+    protozero::proto_utils::internal::FieldMetadataHelper<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(
+      std::move(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 internal {
+class TrackEventInternal;
+}
+
+// Allows adding custom arguments into track events. Example:
+//
+//   TRACE_EVENT_BEGIN("category", "Title",
+//                     [](perfetto::EventContext ctx) {
+//                       auto* dbg = ctx.event()->add_debug_annotations();
+//                       dbg->set_name("name");
+//                       dbg->set_int_value(1234);
+//                     });
+//
+class PERFETTO_EXPORT 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)
+      : event_(event), incremental_state_(incremental_state) {}
+
+  ~EventContext();
+
+  // 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);
+  }
+
+ private:
+  template <typename, size_t, typename, typename>
+  friend class TrackEventInternedDataIndex;
+  friend class internal::TrackEventInternal;
+
+  using TracePacketHandle =
+      ::protozero::MessageHandle<protos::pbzero::TracePacket>;
+
+  EventContext(TracePacketHandle, internal::TrackEventIncrementalState*);
+  EventContext(const EventContext&) = delete;
+
+  TracePacketHandle trace_packet_;
+  protos::pbzero::TrackEvent* event_;
+  internal::TrackEventIncrementalState* incremental_state_;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_EVENT_CONTEXT_H_
+// gen_amalgamated begin header: include/perfetto/tracing/internal/write_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"
+
+namespace perfetto {
+namespace internal {
+
+// Helper function handling filling provided |EventContext| from the provided
+// arguments, which include:
+// - Lambda functions,
+// - Debug annotations.
+//
+// TRACE_EVENT parameters which do not translate to directly writing something
+// into TrackEvent proto (like tracks and timestamps are _not_ covered by this
+// function).
+template <typename... Args, typename TypeCheck = void>
+void WriteTrackEventArgs(EventContext event_context, Args&&... args);
+
+// No arguments means that we don't have to write anything.
+template <>
+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);
+}
+
+}  // namespace
+
+// Write a lambda.
+// TODO(altimin): At the moment lambda takes EventContext, which is
+// non-copyable, so only one lambda is supported and it has to be the last
+// argument.
+template <typename ArgumentFunction,
+          typename ArgFunctionCheck = typename std::enable_if<
+              IsValidTraceLambda<ArgumentFunction>()>::type>
+PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(EventContext event_ctx,
+                                                ArgumentFunction arg_function) {
+  arg_function(std::move(event_ctx));
+}
+
+// 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) {
+  TrackEventInternal::AddDebugAnnotation(&event_ctx, arg_name,
+                                         std::forward<ArgValue>(arg_value));
+  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 Check = base::enable_if_t<
+              std::is_base_of<protozero::proto_utils::FieldMetadataBase,
+                              FieldMetadataType>::value>>
+PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(
+    EventContext event_ctx,
+    protozero::proto_utils::internal::FieldMetadataHelper<FieldMetadataType>
+        field_name,
+    ArgValue&& arg_value,
+    Args&&... args) {
+  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");
+  WriteIntoTracedProto(
+      event_ctx.Wrap(
+          event_ctx.event<typename FieldMetadataType::message_type>()),
+      field_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 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 DynamicCategory final {
+ public:
+  explicit DynamicCategory(const std::string& name_) : name(name_) {}
+  explicit DynamicCategory(const char* name_) : name(name_) {}
+  DynamicCategory() {}
+  ~DynamicCategory() = default;
+
+  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 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 TrackEventConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDisabledCategoriesFieldNumber = 1,
+    kEnabledCategoriesFieldNumber = 2,
+    kDisabledTagsFieldNumber = 3,
+    kEnabledTagsFieldNumber = 4,
+  };
+
+  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(); }
+
+ 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_;
+
+  // 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_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/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 {
+
+// This template provides a way to convert an abstract timestamp into the trace
+// clock timebase in nanoseconds. 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 used by
+// the timestamp as well as its value in nanoseconds.
+//
+// The users should see the specialisation for uint64_t below as an example.
+// Note that the specialisation should be defined in perfetto namespace.
+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 {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;
+}
+
+}  // namespace
+
+// 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;
+
+  // 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 DataSourceType, const TrackEventCategoryRegistry* Registry>
+class TrackEventDataSource
+    : public DataSource<DataSourceType, TrackEventDataSourceTraits> {
+  using Base = DataSource<DataSourceType, TrackEventDataSourceTraits>;
+
+ public:
+  // 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 succesfully added (i.e., the maximum
+  // number of observers wasn't exceeded).
+  static bool AddSessionObserver(TrackEventSessionObserver* observer) {
+    return TrackEventInternal::AddSessionObserver(observer);
+  }
+
+  static void RemoveSessionObserver(TrackEventSessionObserver* observer) {
+    TrackEventInternal::RemoveSessionObserver(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(args);
+  }
+
+  void OnStop(const DataSourceBase::StopArgs& args) override {
+    TrackEventInternal::DisableTracing(*Registry, args);
+  }
+
+  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 = 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});
+  }
+
+  // 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... Arguments>
+  static void TraceForCategory(uint32_t instances,
+                               const CategoryType& category,
+                               const char* event_name,
+                               perfetto::protos::pbzero::TrackEvent::Type type,
+                               Arguments&&... args) PERFETTO_NO_INLINE {
+    TraceForCategoryImpl(instances, category, event_name, type,
+                         TrackEventInternal::kDefaultTrack,
+                         TrackEventInternal::GetTimeNs(),
+                         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... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type>
+  static void TraceForCategory(uint32_t instances,
+                               const CategoryType& category,
+                               const char* event_name,
+                               perfetto::protos::pbzero::TrackEvent::Type type,
+                               TrackType&& track,
+                               Arguments&&... args) PERFETTO_NO_INLINE {
+    TraceForCategoryImpl(
+        instances, category, event_name, type, std::forward<TrackType>(track),
+        TrackEventInternal::GetTimeNs(), std::forward<Arguments>(args)...);
+  }
+
+  // Trace point which takes a timestamp, but not track.
+  template <typename CategoryType,
+            typename TimestampType = uint64_t,
+            typename... Arguments,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type>
+  static void TraceForCategory(uint32_t instances,
+                               const CategoryType& category,
+                               const char* 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 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 TraceForCategory(uint32_t instances,
+                               const CategoryType& category,
+                               const char* 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 ValueType>
+  static void TraceForCategory(uint32_t instances,
+                               const CategoryType& category,
+                               const char*,
+                               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::GetTimeNs(), value);
+  }
+
+  // Trace point with with a timestamp and a counter sample.
+  template <typename CategoryType,
+            typename TimestampType = uint64_t,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type,
+            typename ValueType>
+  static void TraceForCategory(uint32_t instances,
+                               const CategoryType& category,
+                               const char*,
+                               perfetto::protos::pbzero::TrackEvent::Type type,
+                               CounterTrack track,
+                               TimestampType timestamp,
+                               ValueType value) PERFETTO_ALWAYS_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) {
+            event_ctx.event()->set_counter_value(static_cast<int64_t>(value));
+          } else {
+            event_ctx.event()->set_double_counter_value(
+                static_cast<double>(value));
+          }
+        });
+  }
+
+  // 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());
+    });
+  }
+
+  // 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();
+  }
+
+ private:
+  // 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 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 char* event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      const TrackType& track,
+      const TimestampType& timestamp,
+      Arguments&&... args) PERFETTO_ALWAYS_INLINE {
+    using CatTraits = CategoryTraits<CategoryType>;
+    const Category* static_category =
+        CatTraits::GetStaticCategory(Registry, category);
+    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;
+          }
+
+          TraceTimestamp trace_timestamp = ::perfetto::TraceTimestampTraits<
+              TimestampType>::ConvertTimestampToTraceTimeNs(timestamp);
+
+          // Make sure incremental state is valid.
+          TraceWriterBase* trace_writer = ctx.tls_inst_->trace_writer.get();
+          TrackEventIncrementalState* incr_state = ctx.GetIncrementalState();
+          if (incr_state->was_cleared) {
+            incr_state->was_cleared = false;
+            TrackEventInternal::ResetIncrementalState(trace_writer,
+                                                      trace_timestamp);
+          }
+
+          // Write the track descriptor before any event on the track.
+          if (track) {
+            TrackEventInternal::WriteTrackDescriptorIfNeeded(
+                track, trace_writer, incr_state);
+          }
+
+          // Write the event itself.
+          {
+            auto event_ctx = TrackEventInternal::WriteEvent(
+                trace_writer, incr_state, static_category, event_name, type,
+                trace_timestamp);
+            // 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 (&track != &TrackEventInternal::kDefaultTrack)
+              event_ctx.event()->set_track_uuid(track.uuid);
+            WriteTrackEventArgs(std::move(event_ctx),
+                                std::forward<Arguments>(args)...);
+          }  // event_ctx
+        });
+  }
+
+  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());
+    });
+  }
+
+  // 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();
+      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/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(...)                             \
+  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 */                    \
+  PERFETTO_COMPONENT_EXPORT 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);   \
+  PERFETTO_COMPONENT_EXPORT 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()             \
+  namespace internal {                                   \
+  PERFETTO_COMPONENT_EXPORT std::atomic<uint8_t>         \
+      g_category_state_storage[kCategoryCount];          \
+  PERFETTO_COMPONENT_EXPORT 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.
+#define PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE() \
+  struct PERFETTO_COMPONENT_EXPORT TrackEvent               \
+      : public ::perfetto::internal::TrackEventDataSource<  \
+            TrackEvent, &internal::kCategoryRegistry> {}
+
+// 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(category, ...)                           \
+  do {                                                                         \
+    namespace tns = ::PERFETTO_TRACK_EVENT_NAMESPACE;                          \
+    /* Compute the category index outside the lambda to work around a */       \
+    /* GCC 7 bug */                                                            \
+    static constexpr auto PERFETTO_UID(                                        \
+        kCatIndex_ADD_TO_PERFETTO_DEFINE_CATEGORIES_IF_FAILS_) =               \
+        PERFETTO_GET_CATEGORY_INDEX(category);                                 \
+    if (tns::internal::IsDynamicCategory(category)) {                          \
+      tns::TrackEvent::CallIfEnabled(                                          \
+          [&](uint32_t instances) PERFETTO_NO_THREAD_SAFETY_ANALYSIS {         \
+            tns::TrackEvent::TraceForCategory(instances, category,             \
+                                              ##__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::TraceForCategory(                                 \
+                instances,                                                     \
+                PERFETTO_UID(                                                  \
+                    kCatIndex_ADD_TO_PERFETTO_DEFINE_CATEGORIES_IF_FAILS_),    \
+                ##__VA_ARGS__);                                                \
+          });                                                                  \
+    }                                                                          \
+  } while (false)
+
+#define PERFETTO_INTERNAL_SCOPED_TRACK_EVENT(category, name, ...)             \
+  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); }                        \
+    } finalizer;                                                              \
+  } PERFETTO_UID(scoped_event) {                                              \
+    [&]() {                                                                   \
+      TRACE_EVENT_BEGIN(category, name, ##__VA_ARGS__);                       \
+      return 0;                                                               \
+    }()                                                                       \
+  }
+
+#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)))
+
+#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/base/time.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                |
+//  '----------------------------------'
+//
+
+// 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
+#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), ...
+#define PERFETTO_DEFINE_CATEGORIES(...)                        \
+  namespace PERFETTO_TRACK_EVENT_NAMESPACE {                   \
+  /* The list of category names */                             \
+  PERFETTO_INTERNAL_DECLARE_CATEGORIES(__VA_ARGS__)            \
+  /* The track event data source for this set of categories */ \
+  PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE();         \
+  } /* namespace PERFETTO_TRACK_EVENT_NAMESPACE */             \
+  PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(                 \
+      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()      \
+  namespace PERFETTO_TRACK_EVENT_NAMESPACE {       \
+  PERFETTO_INTERNAL_CATEGORY_STORAGE()             \
+  } /* namespace PERFETTO_TRACK_EVENT_NAMESPACE */ \
+  PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(      \
+      PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent,  \
+      perfetto::internal::TrackEventDataSourceTraits)
+
+// 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(                             \
+      category, ::perfetto::internal::GetStaticString(name), \
+      ::perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN, ##__VA_ARGS__)
+
+// End a slice under |category|.
+#define TRACE_EVENT_END(category, ...) \
+  PERFETTO_INTERNAL_TRACK_EVENT(       \
+      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, name, ##__VA_ARGS__)
+
+// Emit a slice which has zero duration.
+#define TRACE_EVENT_INSTANT(category, name, ...)             \
+  PERFETTO_INTERNAL_TRACK_EVENT(                             \
+      category, ::perfetto::internal::GetStaticString(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(                            \
+      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) {
+    // First check if the value exists in the dictionary.
+    auto index_for_field = GetOrCreateIndexForField(ctx->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(
+        ctx->incremental_state_->serialized_interned_data.get(), iid,
+        std::move(value), std::forward<Args>(add_args)...);
+    return iid;
+  }
+
+ private:
+  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
+
+// ----------------------------------------------------------------------------
+// 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 };
+
+}  // 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';
+static constexpr char TRACE_EVENT_PHASE_ENTER_CONTEXT = '(';
+static constexpr char TRACE_EVENT_PHASE_LEAVE_CONTEXT = ')';
+
+// 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
+
+// ----------------------------------------------------------------------------
+// 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
+ConvertThreadId(const PerfettoLegacyCurrentThreadId&);
+
+}  // namespace legacy
+
+namespace internal {
+
+// LegacyTraceId encapsulates an ID that can either be an integer or pointer.
+class PERFETTO_EXPORT 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)) {}
+  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;
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#if PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+
+namespace perfetto {
+namespace internal {
+
+class PERFETTO_EXPORT 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 {
+    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.
+    //
+    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);
+      }
+    }
+  }
+
+  // No arguments.
+  static void AddDebugAnnotations(EventContext*) {}
+
+  // One argument.
+  template <typename ArgType>
+  static void AddDebugAnnotations(EventContext* ctx,
+                                  const char* arg_name,
+                                  ArgType&& arg_value) {
+    TrackEventInternal::AddDebugAnnotation(ctx, arg_name, arg_value);
+  }
+
+  // Two arguments.
+  template <typename ArgType, typename ArgType2>
+  static void AddDebugAnnotations(EventContext* ctx,
+                                  const char* arg_name,
+                                  ArgType&& arg_value,
+                                  const char* arg_name2,
+                                  ArgType2&& arg_value2) {
+    TrackEventInternal::AddDebugAnnotation(ctx, arg_name, arg_value);
+    TrackEventInternal::AddDebugAnnotation(ctx, arg_name2, arg_value2);
+  }
+
+ 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);
+    }
+  }
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+// 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(                                              \
+      category,                                                               \
+      ::perfetto::internal::GetStaticString(::perfetto::StaticString{name}),  \
+      ::perfetto::internal::TrackEventLegacy::PhaseToType(phase), track,      \
+      ##__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;                        \
+    /* 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_ON_TRACK(                         \
+              phase, category, name, ::perfetto::Track::Global(0),         \
+              ##__VA_ARGS__);                                              \
+          return;                                                          \
+        case TRACE_EVENT_SCOPE_PROCESS:                                    \
+          PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK(                         \
+              phase, category, name, ::perfetto::ProcessTrack::Current(),  \
+              ##__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_ON_TRACK(                             \
+          phase, category, name, TrackEventInternal::kDefaultTrack,        \
+          ##__VA_ARGS__);                                                  \
+    } else {                                                               \
+      PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK(                             \
+          phase, category, name,                                           \
+          ::perfetto::legacy::ConvertThreadId(thread_id), ##__VA_ARGS__);  \
+    }                                                                      \
+  }()
+
+#define INTERNAL_TRACE_EVENT_ADD(phase, category, name, flags, ...)        \
+  PERFETTO_INTERNAL_LEGACY_EVENT(                                          \
+      phase, category, name, flags, ::perfetto::legacy::kCurrentThreadId,  \
+      [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS { \
+        using ::perfetto::internal::TrackEventLegacy;                      \
+        TrackEventLegacy::WriteLegacyEvent(std::move(ctx), phase, flags,   \
+                                           ##__VA_ARGS__);                 \
+      })
+
+// PERFETTO_INTERNAL_SCOPED_TRACK_EVENT does not require GetStaticString, as it
+// uses TRACE_EVENT_BEGIN/END internally, which already have this call.
+#define INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, ...)               \
+  PERFETTO_INTERNAL_SCOPED_TRACK_EVENT(                                    \
+      category, ::perfetto::StaticString{name},                            \
+      [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS { \
+        using ::perfetto::internal::TrackEventLegacy;                      \
+        TrackEventLegacy::AddDebugAnnotations(&ctx, ##__VA_ARGS__);        \
+      })
+
+// PERFETTO_INTERNAL_SCOPED_TRACK_EVENT does not require GetStaticString, as it
+// uses TRACE_EVENT_BEGIN/END internally, which already have this call.
+#define INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category, name, bind_id,   \
+                                                  flags, ...)                \
+  PERFETTO_INTERNAL_SCOPED_TRACK_EVENT(                                      \
+      category, ::perfetto::StaticString{name},                              \
+      [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS {   \
+        using ::perfetto::internal::TrackEventLegacy;                        \
+        ::perfetto::internal::LegacyTraceId PERFETTO_UID(trace_id){bind_id}; \
+        TrackEventLegacy::WriteLegacyEventWithIdAndTid(                      \
+            std::move(ctx), TRACE_EVENT_PHASE_BEGIN, flags,                  \
+            PERFETTO_UID(trace_id), TRACE_EVENT_API_CURRENT_THREAD_ID,       \
+            ##__VA_ARGS__);                                                  \
+      })
+
+#define INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(phase, category, name,     \
+                                                timestamp, flags, ...)     \
+  PERFETTO_INTERNAL_LEGACY_EVENT(                                          \
+      phase, category, name, flags, ::perfetto::legacy::kCurrentThreadId,  \
+      timestamp,                                                           \
+      [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS { \
+        using ::perfetto::internal::TrackEventLegacy;                      \
+        TrackEventLegacy::WriteLegacyEvent(std::move(ctx), phase, flags,   \
+                                           ##__VA_ARGS__);                 \
+      })
+
+#define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                  \
+    phase, category, name, id, thread_id, timestamp, flags, ...)             \
+  PERFETTO_INTERNAL_LEGACY_EVENT(                                            \
+      phase, category, name, flags, thread_id, timestamp,                    \
+      [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS {   \
+        using ::perfetto::internal::TrackEventLegacy;                        \
+        ::perfetto::internal::LegacyTraceId PERFETTO_UID(trace_id){id};      \
+        TrackEventLegacy::WriteLegacyEventWithIdAndTid(                      \
+            std::move(ctx), phase, flags, PERFETTO_UID(trace_id), thread_id, \
+            ##__VA_ARGS__);                                                  \
+      })
+
+#define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category, name, id, flags, \
+                                         ...)                              \
+  PERFETTO_INTERNAL_LEGACY_EVENT(                                          \
+      phase, category, name, flags, ::perfetto::legacy::kCurrentThreadId,  \
+      [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS { \
+        using ::perfetto::internal::TrackEventLegacy;                      \
+        ::perfetto::internal::LegacyTraceId PERFETTO_UID(trace_id){id};    \
+        TrackEventLegacy::WriteLegacyEventWithIdAndTid(                    \
+            std::move(ctx), phase, flags, PERFETTO_UID(trace_id),          \
+            TRACE_EVENT_API_CURRENT_THREAD_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, 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, 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, arg1_val, \
+                                  arg2_name, 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, arg1_val, \
+                                            arg2_name, 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, 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, arg1_val, \
+                           arg2_name, arg2_val)
+#define TRACE_EVENT_COPY_INSTANT0(category_group, name, scope)              \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
+                           TRACE_EVENT_FLAG_COPY | scope)
+#define TRACE_EVENT_COPY_INSTANT1(category_group, name, scope, arg1_name,   \
+                                  arg1_val)                                 \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
+                           TRACE_EVENT_FLAG_COPY | scope, arg1_name, 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, name,    \
+                           TRACE_EVENT_FLAG_COPY | scope, arg1_name, arg1_val, \
+                           arg2_name, 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, 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, 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, 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, arg1_val,    \
+                           arg2_name, 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, 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, name,  \
+                           TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val,     \
+                           arg2_name, 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, name, id, thread_id, \
+      timestamp, TRACE_EVENT_FLAG_COPY)
+#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, name, id, thread_id, \
+      timestamp, TRACE_EVENT_FLAG_COPY, arg1_name, 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, name, id, thread_id, \
+      timestamp, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name,   \
+      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, 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, arg1_val,         \
+                           arg2_name, 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, 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, name,  \
+                           TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val,   \
+                           arg2_name, 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, 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, arg1_val, arg2_name, arg2_val)
+
+#define TRACE_EVENT_COPY_MARK(category_group, name)                      \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_MARK, category_group, name, \
+                           TRACE_EVENT_FLAG_COPY)
+
+#define TRACE_EVENT_COPY_MARK1(category_group, name, arg1_name, arg1_val) \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_MARK, category_group, name,  \
+                           TRACE_EVENT_FLAG_COPY, arg1_name, 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, name, timestamp,    \
+                                          TRACE_EVENT_FLAG_COPY)
+
+// 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, name, id, thread_id, \
+      timestamp, TRACE_EVENT_FLAG_COPY)
+#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, name, id, thread_id,  \
+      timestamp, TRACE_EVENT_FLAG_COPY, arg1_name, 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, name, id, thread_id,  \
+      timestamp, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name,  \
+      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, name, \
+                           TRACE_EVENT_FLAG_COPY, "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, name, \
+                           TRACE_EVENT_FLAG_COPY, 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, \
+                                   name, id, TRACE_EVENT_FLAG_COPY, "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, \
+                                   name, id, TRACE_EVENT_FLAG_COPY,           \
+                                   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, 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, arg1_val, arg2_name, 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, name, id,      \
+                                   TRACE_EVENT_FLAG_COPY)
+#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, name, id,               \
+                                   TRACE_EVENT_FLAG_COPY, arg1_name, 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, name, id,             \
+      TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, 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, 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, arg1_val, arg2_name, 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, name, id,                 \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY)
+#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, 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, 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, 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, arg1_val, arg2_name, 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, name, id,    \
+                                   TRACE_EVENT_FLAG_COPY)
+#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, name, id,             \
+                                   TRACE_EVENT_FLAG_COPY, arg1_name, 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, name, id,             \
+      TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, 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, 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, arg1_val, arg2_name, 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, name, id,                 \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY)
+#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, 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, arg1_val, arg2_name, 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, 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, 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, arg1_val, arg2_name, 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, 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, arg1_val, arg2_name, 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, name, id,        \
+      TRACE_EVENT_FLAG_ASYNC_TTS | TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
+      arg2_name, 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, name, id,          \
+      TRACE_EVENT_FLAG_ASYNC_TTS | TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
+      arg2_name, 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, 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, arg1_val, arg2_name, 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, name, id,               \
+                                   TRACE_EVENT_FLAG_COPY)
+#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, name, id,               \
+                                   TRACE_EVENT_FLAG_COPY, arg1_name, 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, name, id, \
+      TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, 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, name, id,             \
+                                   TRACE_EVENT_FLAG_COPY)
+#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, name, id, \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY)
+#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, name, id,    \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY, \
+      arg1_name, 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, name, id, \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY)
+#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, arg1_val, arg2_name, 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, 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)
+
+// Context events.
+#define TRACE_EVENT_ENTER_CONTEXT(category_group, name, context)    \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ENTER_CONTEXT, \
+                                   category_group, name, context,   \
+                                   TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_LEAVE_CONTEXT(category_group, name, context)    \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_LEAVE_CONTEXT, \
+                                   category_group, name, context,   \
+                                   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) (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/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 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 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 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 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 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 CommitDataRequest_ChunksToMove : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPageFieldNumber = 1,
+    kChunkFieldNumber = 2,
+    kTargetBufferFieldNumber = 3,
+  };
+
+  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); }
+
+ private:
+  uint32_t page_{};
+  uint32_t chunk_{};
+  uint32_t target_buffer_{};
+
+  // 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_COMMIT_DATA_REQUEST_PROTO_CPP_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 DataSourceDescriptor : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kWillNotifyOnStopFieldNumber = 2,
+    kWillNotifyOnStartFieldNumber = 3,
+    kHandlesIncrementalStateClearFieldNumber = 4,
+    kGpuCounterDescriptorFieldNumber = 5,
+    kTrackEventDescriptorFieldNumber = 6,
+  };
+
+  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_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); }
+
+  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); }
+
+ private:
+  std::string name_{};
+  bool will_notify_on_stop_{};
+  bool will_notify_on_start_{};
+  bool handles_incremental_state_clear_{};
+  std::string gpu_counter_descriptor_;  // [lazy=true]
+  std::string track_event_descriptor_;  // [lazy=true]
+
+  // 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_COMMON_DATA_SOURCE_DESCRIPTOR_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 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 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 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 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 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 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,
+    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_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_{};
+  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 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 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 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 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/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 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 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 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 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_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,
+};
+enum ObservableEvents_DataSourceInstanceState : int {
+  ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED = 1,
+  ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED = 2,
+};
+
+class PERFETTO_EXPORT ObservableEvents : public ::protozero::CppMessageObj {
+ public:
+  using DataSourceInstanceStateChange = ObservableEvents_DataSourceInstanceStateChange;
+  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_MIN = ObservableEvents_Type_TYPE_UNSPECIFIED;
+  static constexpr auto Type_MAX = ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED;
+  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,
+  };
+
+  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); }
+
+ private:
+  std::vector<ObservableEvents_DataSourceInstanceStateChange> instance_state_changes_;
+  bool all_data_sources_started_{};
+
+  // 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 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;
+}  // 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_HW_CPU_CYCLES = 10,
+  PerfEvents_Counter_HW_INSTRUCTIONS = 11,
+};
+
+class PERFETTO_EXPORT 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 HW_CPU_CYCLES = PerfEvents_Counter_HW_CPU_CYCLES;
+  static constexpr auto HW_INSTRUCTIONS = PerfEvents_Counter_HW_INSTRUCTIONS;
+  static constexpr auto Counter_MIN = PerfEvents_Counter_UNKNOWN_COUNTER;
+  static constexpr auto Counter_MAX = PerfEvents_Counter_HW_INSTRUCTIONS;
+  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 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 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 PerfEvents_Timebase : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kFrequencyFieldNumber = 2,
+    kPeriodFieldNumber = 1,
+    kCounterFieldNumber = 4,
+    kTracepointFieldNumber = 3,
+    kRawEventFieldNumber = 5,
+    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_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_;
+  std::string name_{};
+
+  // 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_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_BufferStats;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT TraceStats : public ::protozero::CppMessageObj {
+ public:
+  using BufferStats = TraceStats_BufferStats;
+  using FilterStats = TraceStats_FilterStats;
+  enum FieldNumbers {
+    kBufferStatsFieldNumber = 1,
+    kProducersConnectedFieldNumber = 2,
+    kProducersSeenFieldNumber = 3,
+    kDataSourcesRegisteredFieldNumber = 4,
+    kDataSourcesSeenFieldNumber = 5,
+    kTracingSessionsFieldNumber = 6,
+    kTotalBuffersFieldNumber = 7,
+    kChunksDiscardedFieldNumber = 8,
+    kPatchesDiscardedFieldNumber = 9,
+    kInvalidPacketsFieldNumber = 10,
+    kFilterStatsFieldNumber = 11,
+  };
+
+  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();
+
+  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(); }
+
+ private:
+  std::vector<TraceStats_BufferStats> buffer_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_;
+
+  // 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 TraceStats_FilterStats : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kInputPacketsFieldNumber = 1,
+    kInputBytesFieldNumber = 2,
+    kOutputBytesFieldNumber = 3,
+    kErrorsFieldNumber = 4,
+  };
+
+  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); }
+
+ private:
+  uint64_t input_packets_{};
+  uint64_t input_bytes_{};
+  uint64_t output_bytes_{};
+  uint64_t errors_{};
+
+  // 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 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 TracingServiceCapabilities : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kHasQueryCapabilitiesFieldNumber = 1,
+    kObservableEventsFieldNumber = 2,
+    kHasTraceConfigOutputPathFieldNumber = 3,
+  };
+
+  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); }
+
+ private:
+  bool has_query_capabilities_{};
+  std::vector<ObservableEvents_Type> observable_events_;
+  bool has_trace_config_output_path_{};
+
+  // 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_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_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 TracingServiceState : public ::protozero::CppMessageObj {
+ public:
+  using Producer = TracingServiceState_Producer;
+  using DataSource = TracingServiceState_DataSource;
+  enum FieldNumbers {
+    kProducersFieldNumber = 1,
+    kDataSourcesFieldNumber = 2,
+    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();
+
+  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_;
+  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<6> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT 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 TracingServiceState_Producer : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+    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_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 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<5> _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 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 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,
+  };
+
+  using FieldMetadata_EnergyConsumers =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidEnergyConsumer,
+      AndroidEnergyConsumerDescriptor>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EnergyConsumers kEnergyConsumers() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_EnergyConsumerId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidEnergyConsumer>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EnergyConsumerId kEnergyConsumerId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ordinal kOrdinal() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  void set_type(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Type::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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,
+};
+
+const AndroidLogId AndroidLogId_MIN = LID_DEFAULT;
+const AndroidLogId AndroidLogId_MAX = LID_KERNEL;
+
+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,
+};
+
+const AndroidLogPriority AndroidLogPriority_MIN = PRIO_UNSPECIFIED;
+const AndroidLogPriority AndroidLogPriority_MAX = PRIO_FATAL;
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// 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,
+};
+
+const BuiltinClock BuiltinClock_MIN = BUILTIN_CLOCK_UNKNOWN;
+const BuiltinClock BuiltinClock_MAX = BUILTIN_CLOCK_MAX_ID;
+
+} // 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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChunksToMove kChunksToMove() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChunksToPatch kChunksToPatch() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FlushRequestId kFlushRequestId() { return {}; }
+  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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TargetBuffer kTargetBuffer() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WriterId kWriterId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChunkId kChunkId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Patches kPatches() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HasMorePatches kHasMorePatches() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CommitDataRequest_ChunkToPatch_Patch>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Offset kOffset() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Data kData() { return {}; }
+  void set_data(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Data::kFieldId, data, 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=*/3, /*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(); }
+};
+
+class CommitDataRequest_ChunksToMove : public ::protozero::Message {
+ public:
+  using Decoder = CommitDataRequest_ChunksToMove_Decoder;
+  enum : int32_t {
+    kPageFieldNumber = 1,
+    kChunkFieldNumber = 2,
+    kTargetBufferFieldNumber = 3,
+  };
+
+  using FieldMetadata_Page =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CommitDataRequest_ChunksToMove>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Page kPage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Chunk kChunk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TargetBuffer kTargetBuffer() { return {}; }
+  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);
+  }
+};
+
+} // 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 GpuCounterDescriptor;
+class TrackEventDescriptor;
+
+class DataSourceDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*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_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_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(); }
+};
+
+class DataSourceDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = DataSourceDescriptor_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kWillNotifyOnStopFieldNumber = 2,
+    kWillNotifyOnStartFieldNumber = 3,
+    kHandlesIncrementalStateClearFieldNumber = 4,
+    kGpuCounterDescriptorFieldNumber = 5,
+    kTrackEventDescriptorFieldNumber = 6,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DataSourceDescriptor>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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_WillNotifyOnStop =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DataSourceDescriptor>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WillNotifyOnStop kWillNotifyOnStop() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WillNotifyOnStart kWillNotifyOnStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HandlesIncrementalStateClear kHandlesIncrementalStateClear() { return {}; }
+  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_GpuCounterDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuCounterDescriptor,
+      DataSourceDescriptor>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuCounterDescriptor kGpuCounterDescriptor() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrackEventDescriptor kTrackEventDescriptor() { return {}; }
+  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());
+  }
+
+};
+
+} // 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 FileDescriptorProto;
+class OneofDescriptorProto;
+class OneofOptions;
+enum FieldDescriptorProto_Label : int32_t;
+enum FieldDescriptorProto_Type : int32_t;
+
+enum FieldDescriptorProto_Type : int32_t {
+  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,
+};
+
+const FieldDescriptorProto_Type FieldDescriptorProto_Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE;
+const FieldDescriptorProto_Type FieldDescriptorProto_Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64;
+
+enum FieldDescriptorProto_Label : int32_t {
+  FieldDescriptorProto_Label_LABEL_OPTIONAL = 1,
+  FieldDescriptorProto_Label_LABEL_REQUIRED = 2,
+  FieldDescriptorProto_Label_LABEL_REPEATED = 3,
+};
+
+const FieldDescriptorProto_Label FieldDescriptorProto_Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL;
+const FieldDescriptorProto_Label FieldDescriptorProto_Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED;
+
+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;
+};
+
+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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      EnumValueDescriptorProto>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Number kNumber() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      EnumDescriptorProto>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Value kValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReservedName kReservedName() { return {}; }
+  void add_reserved_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ReservedName::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      OneofDescriptorProto>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Options kOptions() { return {}; }
+  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_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,
+    kOneofIndexFieldNumber = 9,
+  };
+  using Type = ::perfetto::protos::pbzero::FieldDescriptorProto_Type;
+  using Label = ::perfetto::protos::pbzero::FieldDescriptorProto_Label;
+  static const Type TYPE_DOUBLE = FieldDescriptorProto_Type_TYPE_DOUBLE;
+  static const Type TYPE_FLOAT = FieldDescriptorProto_Type_TYPE_FLOAT;
+  static const Type TYPE_INT64 = FieldDescriptorProto_Type_TYPE_INT64;
+  static const Type TYPE_UINT64 = FieldDescriptorProto_Type_TYPE_UINT64;
+  static const Type TYPE_INT32 = FieldDescriptorProto_Type_TYPE_INT32;
+  static const Type TYPE_FIXED64 = FieldDescriptorProto_Type_TYPE_FIXED64;
+  static const Type TYPE_FIXED32 = FieldDescriptorProto_Type_TYPE_FIXED32;
+  static const Type TYPE_BOOL = FieldDescriptorProto_Type_TYPE_BOOL;
+  static const Type TYPE_STRING = FieldDescriptorProto_Type_TYPE_STRING;
+  static const Type TYPE_GROUP = FieldDescriptorProto_Type_TYPE_GROUP;
+  static const Type TYPE_MESSAGE = FieldDescriptorProto_Type_TYPE_MESSAGE;
+  static const Type TYPE_BYTES = FieldDescriptorProto_Type_TYPE_BYTES;
+  static const Type TYPE_UINT32 = FieldDescriptorProto_Type_TYPE_UINT32;
+  static const Type TYPE_ENUM = FieldDescriptorProto_Type_TYPE_ENUM;
+  static const Type TYPE_SFIXED32 = FieldDescriptorProto_Type_TYPE_SFIXED32;
+  static const Type TYPE_SFIXED64 = FieldDescriptorProto_Type_TYPE_SFIXED64;
+  static const Type TYPE_SINT32 = FieldDescriptorProto_Type_TYPE_SINT32;
+  static const Type TYPE_SINT64 = FieldDescriptorProto_Type_TYPE_SINT64;
+  static const Label LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL;
+  static const Label LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED;
+  static const Label LABEL_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED;
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FieldDescriptorProto>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Number kNumber() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Label kLabel() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TypeName kTypeName() { return {}; }
+  void set_type_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TypeName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Extendee kExtendee() { return {}; }
+  void set_extendee(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Extendee::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DefaultValue kDefaultValue() { return {}; }
+  void set_default_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DefaultValue::kFieldId, data, 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_OneofIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FieldDescriptorProto>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OneofIndex kOneofIndex() { return {}; }
+  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 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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Field kField() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Extension kExtension() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NestedType kNestedType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EnumType kEnumType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OneofDecl kOneofDecl() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReservedRange kReservedRange() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReservedName kReservedName() { return {}; }
+  void add_reserved_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ReservedName::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DescriptorProto_ReservedRange>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Start kStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_End kEnd() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FileDescriptorProto>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Package kPackage() { return {}; }
+  void set_package(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Package::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dependency kDependency() { return {}; }
+  void add_dependency(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Dependency::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PublicDependency kPublicDependency() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WeakDependency kWeakDependency() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MessageType kMessageType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EnumType kEnumType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Extension kExtension() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_File =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FileDescriptorProto,
+      FileDescriptorSet>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_File kFile() { return {}; }
+  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/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;
+enum GpuCounterDescriptor_GpuCounterGroup : int32_t;
+enum GpuCounterDescriptor_MeasureUnit : int32_t;
+
+enum GpuCounterDescriptor_GpuCounterGroup : int32_t {
+  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,
+};
+
+const GpuCounterDescriptor_GpuCounterGroup GpuCounterDescriptor_GpuCounterGroup_MIN = GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED;
+const GpuCounterDescriptor_GpuCounterGroup GpuCounterDescriptor_GpuCounterGroup_MAX = GpuCounterDescriptor_GpuCounterGroup_COMPUTE;
+
+enum GpuCounterDescriptor_MeasureUnit : int32_t {
+  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,
+};
+
+const GpuCounterDescriptor_MeasureUnit GpuCounterDescriptor_MeasureUnit_MIN = GpuCounterDescriptor_MeasureUnit_NONE;
+const GpuCounterDescriptor_MeasureUnit GpuCounterDescriptor_MeasureUnit_MAX = GpuCounterDescriptor_MeasureUnit_INSTRUCTION;
+
+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,
+  };
+  using GpuCounterSpec = ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterSpec;
+  using GpuCounterBlock = ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterBlock;
+  using GpuCounterGroup = ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup;
+  using MeasureUnit = ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit;
+  static const GpuCounterGroup UNCLASSIFIED = GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED;
+  static const GpuCounterGroup SYSTEM = GpuCounterDescriptor_GpuCounterGroup_SYSTEM;
+  static const GpuCounterGroup VERTICES = GpuCounterDescriptor_GpuCounterGroup_VERTICES;
+  static const GpuCounterGroup FRAGMENTS = GpuCounterDescriptor_GpuCounterGroup_FRAGMENTS;
+  static const GpuCounterGroup PRIMITIVES = GpuCounterDescriptor_GpuCounterGroup_PRIMITIVES;
+  static const GpuCounterGroup MEMORY = GpuCounterDescriptor_GpuCounterGroup_MEMORY;
+  static const GpuCounterGroup COMPUTE = GpuCounterDescriptor_GpuCounterGroup_COMPUTE;
+  static const MeasureUnit NONE = GpuCounterDescriptor_MeasureUnit_NONE;
+  static const MeasureUnit BIT = GpuCounterDescriptor_MeasureUnit_BIT;
+  static const MeasureUnit KILOBIT = GpuCounterDescriptor_MeasureUnit_KILOBIT;
+  static const MeasureUnit MEGABIT = GpuCounterDescriptor_MeasureUnit_MEGABIT;
+  static const MeasureUnit GIGABIT = GpuCounterDescriptor_MeasureUnit_GIGABIT;
+  static const MeasureUnit TERABIT = GpuCounterDescriptor_MeasureUnit_TERABIT;
+  static const MeasureUnit PETABIT = GpuCounterDescriptor_MeasureUnit_PETABIT;
+  static const MeasureUnit BYTE = GpuCounterDescriptor_MeasureUnit_BYTE;
+  static const MeasureUnit KILOBYTE = GpuCounterDescriptor_MeasureUnit_KILOBYTE;
+  static const MeasureUnit MEGABYTE = GpuCounterDescriptor_MeasureUnit_MEGABYTE;
+  static const MeasureUnit GIGABYTE = GpuCounterDescriptor_MeasureUnit_GIGABYTE;
+  static const MeasureUnit TERABYTE = GpuCounterDescriptor_MeasureUnit_TERABYTE;
+  static const MeasureUnit PETABYTE = GpuCounterDescriptor_MeasureUnit_PETABYTE;
+  static const MeasureUnit HERTZ = GpuCounterDescriptor_MeasureUnit_HERTZ;
+  static const MeasureUnit KILOHERTZ = GpuCounterDescriptor_MeasureUnit_KILOHERTZ;
+  static const MeasureUnit MEGAHERTZ = GpuCounterDescriptor_MeasureUnit_MEGAHERTZ;
+  static const MeasureUnit GIGAHERTZ = GpuCounterDescriptor_MeasureUnit_GIGAHERTZ;
+  static const MeasureUnit TERAHERTZ = GpuCounterDescriptor_MeasureUnit_TERAHERTZ;
+  static const MeasureUnit PETAHERTZ = GpuCounterDescriptor_MeasureUnit_PETAHERTZ;
+  static const MeasureUnit NANOSECOND = GpuCounterDescriptor_MeasureUnit_NANOSECOND;
+  static const MeasureUnit MICROSECOND = GpuCounterDescriptor_MeasureUnit_MICROSECOND;
+  static const MeasureUnit MILLISECOND = GpuCounterDescriptor_MeasureUnit_MILLISECOND;
+  static const MeasureUnit SECOND = GpuCounterDescriptor_MeasureUnit_SECOND;
+  static const MeasureUnit MINUTE = GpuCounterDescriptor_MeasureUnit_MINUTE;
+  static const MeasureUnit HOUR = GpuCounterDescriptor_MeasureUnit_HOUR;
+  static const MeasureUnit VERTEX = GpuCounterDescriptor_MeasureUnit_VERTEX;
+  static const MeasureUnit PIXEL = GpuCounterDescriptor_MeasureUnit_PIXEL;
+  static const MeasureUnit TRIANGLE = GpuCounterDescriptor_MeasureUnit_TRIANGLE;
+  static const MeasureUnit PRIMITIVE = GpuCounterDescriptor_MeasureUnit_PRIMITIVE;
+  static const MeasureUnit FRAGMENT = GpuCounterDescriptor_MeasureUnit_FRAGMENT;
+  static const MeasureUnit MILLIWATT = GpuCounterDescriptor_MeasureUnit_MILLIWATT;
+  static const MeasureUnit WATT = GpuCounterDescriptor_MeasureUnit_WATT;
+  static const MeasureUnit KILOWATT = GpuCounterDescriptor_MeasureUnit_KILOWATT;
+  static const MeasureUnit JOULE = GpuCounterDescriptor_MeasureUnit_JOULE;
+  static const MeasureUnit VOLT = GpuCounterDescriptor_MeasureUnit_VOLT;
+  static const MeasureUnit AMPERE = GpuCounterDescriptor_MeasureUnit_AMPERE;
+  static const MeasureUnit CELSIUS = GpuCounterDescriptor_MeasureUnit_CELSIUS;
+  static const MeasureUnit FAHRENHEIT = GpuCounterDescriptor_MeasureUnit_FAHRENHEIT;
+  static const MeasureUnit KELVIN = GpuCounterDescriptor_MeasureUnit_KELVIN;
+  static const MeasureUnit PERCENT = GpuCounterDescriptor_MeasureUnit_PERCENT;
+  static const MeasureUnit INSTRUCTION = GpuCounterDescriptor_MeasureUnit_INSTRUCTION;
+
+  using FieldMetadata_Specs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuCounterDescriptor_GpuCounterSpec,
+      GpuCounterDescriptor>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Specs kSpecs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Blocks kBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MinSamplingPeriodNs kMinSamplingPeriodNs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MaxSamplingPeriodNs kMaxSamplingPeriodNs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SupportsInstrumentedSampling kSupportsInstrumentedSampling() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_BlockId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuCounterDescriptor_GpuCounterBlock>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockId kBlockId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockCapacity kBlockCapacity() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Description kDescription() { return {}; }
+  void set_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Description::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CounterIds kCounterIds() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_CounterId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuCounterDescriptor_GpuCounterSpec>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CounterId kCounterId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Description kDescription() { return {}; }
+  void set_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Description::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IntPeakValue kIntPeakValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DoublePeakValue kDoublePeakValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NumeratorUnits kNumeratorUnits() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DenominatorUnits kDenominatorUnits() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SelectByDefault kSelectByDefault() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Groups kGroups() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InterceptorDescriptor>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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_DataSourceInstanceStateChange;
+enum ObservableEvents_DataSourceInstanceState : int32_t;
+
+enum ObservableEvents_Type : int32_t {
+  ObservableEvents_Type_TYPE_UNSPECIFIED = 0,
+  ObservableEvents_Type_TYPE_DATA_SOURCES_INSTANCES = 1,
+  ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED = 2,
+};
+
+const ObservableEvents_Type ObservableEvents_Type_MIN = ObservableEvents_Type_TYPE_UNSPECIFIED;
+const ObservableEvents_Type ObservableEvents_Type_MAX = ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED;
+
+enum ObservableEvents_DataSourceInstanceState : int32_t {
+  ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED = 1,
+  ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED = 2,
+};
+
+const ObservableEvents_DataSourceInstanceState ObservableEvents_DataSourceInstanceState_MIN = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED;
+const ObservableEvents_DataSourceInstanceState ObservableEvents_DataSourceInstanceState_MAX = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED;
+
+class ObservableEvents_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*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(); }
+};
+
+class ObservableEvents : public ::protozero::Message {
+ public:
+  using Decoder = ObservableEvents_Decoder;
+  enum : int32_t {
+    kInstanceStateChangesFieldNumber = 1,
+    kAllDataSourcesStartedFieldNumber = 2,
+  };
+  using DataSourceInstanceStateChange = ::perfetto::protos::pbzero::ObservableEvents_DataSourceInstanceStateChange;
+  using Type = ::perfetto::protos::pbzero::ObservableEvents_Type;
+  using DataSourceInstanceState = ::perfetto::protos::pbzero::ObservableEvents_DataSourceInstanceState;
+  static const Type TYPE_UNSPECIFIED = ObservableEvents_Type_TYPE_UNSPECIFIED;
+  static const Type TYPE_DATA_SOURCES_INSTANCES = ObservableEvents_Type_TYPE_DATA_SOURCES_INSTANCES;
+  static const Type TYPE_ALL_DATA_SOURCES_STARTED = ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED;
+  static const DataSourceInstanceState DATA_SOURCE_INSTANCE_STATE_STOPPED = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED;
+  static const DataSourceInstanceState DATA_SOURCE_INSTANCE_STATE_STARTED = ObservableEvents_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InstanceStateChanges kInstanceStateChanges() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllDataSourcesStarted kAllDataSourcesStarted() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_ProducerName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ObservableEvents_DataSourceInstanceStateChange>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProducerName kProducerName() { return {}; }
+  void set_producer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DataSourceName kDataSourceName() { return {}; }
+  void set_data_source_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DataSourceName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_State kState() { return {}; }
+  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;
+enum PerfEvents_Counter : int32_t;
+
+enum PerfEvents_Counter : int32_t {
+  PerfEvents_Counter_UNKNOWN_COUNTER = 0,
+  PerfEvents_Counter_SW_CPU_CLOCK = 1,
+  PerfEvents_Counter_SW_PAGE_FAULTS = 2,
+  PerfEvents_Counter_HW_CPU_CYCLES = 10,
+  PerfEvents_Counter_HW_INSTRUCTIONS = 11,
+};
+
+const PerfEvents_Counter PerfEvents_Counter_MIN = PerfEvents_Counter_UNKNOWN_COUNTER;
+const PerfEvents_Counter PerfEvents_Counter_MAX = PerfEvents_Counter_HW_INSTRUCTIONS;
+
+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;
+  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 const Counter UNKNOWN_COUNTER = PerfEvents_Counter_UNKNOWN_COUNTER;
+  static const Counter SW_CPU_CLOCK = PerfEvents_Counter_SW_CPU_CLOCK;
+  static const Counter SW_PAGE_FAULTS = PerfEvents_Counter_SW_PAGE_FAULTS;
+  static const Counter HW_CPU_CYCLES = PerfEvents_Counter_HW_CPU_CYCLES;
+  static const Counter HW_INSTRUCTIONS = PerfEvents_Counter_HW_INSTRUCTIONS;
+};
+
+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,
+  };
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEvents_RawEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Config kConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Config1 kConfig1() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Config2 kConfig2() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfEvents_Tracepoint>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Filter kFilter() { return {}; }
+  void set_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Filter::kFieldId, data, 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=*/10, /*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_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,
+    kNameFieldNumber = 10,
+  };
+
+  using FieldMetadata_Frequency =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfEvents_Timebase>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Frequency kFrequency() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Period kPeriod() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Counter kCounter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tracepoint kTracepoint() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RawEvent kRawEvent() { return {}; }
+  template <typename T = PerfEvents_RawEvent> T* set_raw_event() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfEvents_Timebase>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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,
+};
+
+const MeminfoCounters MeminfoCounters_MIN = MEMINFO_UNSPECIFIED;
+const MeminfoCounters MeminfoCounters_MAX = MEMINFO_CMA_FREE;
+
+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,
+};
+
+const VmstatCounters VmstatCounters_MIN = VMSTAT_UNSPECIFIED;
+const VmstatCounters VmstatCounters_MAX = VMSTAT_WORKINGSET_RESTORE;
+
+} // 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_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*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_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(); }
+};
+
+class TraceStats : public ::protozero::Message {
+ public:
+  using Decoder = TraceStats_Decoder;
+  enum : int32_t {
+    kBufferStatsFieldNumber = 1,
+    kProducersConnectedFieldNumber = 2,
+    kProducersSeenFieldNumber = 3,
+    kDataSourcesRegisteredFieldNumber = 4,
+    kDataSourcesSeenFieldNumber = 5,
+    kTracingSessionsFieldNumber = 6,
+    kTotalBuffersFieldNumber = 7,
+    kChunksDiscardedFieldNumber = 8,
+    kPatchesDiscardedFieldNumber = 9,
+    kInvalidPacketsFieldNumber = 10,
+    kFilterStatsFieldNumber = 11,
+  };
+  using BufferStats = ::perfetto::protos::pbzero::TraceStats_BufferStats;
+  using FilterStats = ::perfetto::protos::pbzero::TraceStats_FilterStats;
+
+  using FieldMetadata_BufferStats =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceStats_BufferStats,
+      TraceStats>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BufferStats kBufferStats() { return {}; }
+  template <typename T = TraceStats_BufferStats> T* add_buffer_stats() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ProducersConnected =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceStats>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProducersConnected kProducersConnected() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProducersSeen kProducersSeen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DataSourcesRegistered kDataSourcesRegistered() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DataSourcesSeen kDataSourcesSeen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TracingSessions kTracingSessions() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TotalBuffers kTotalBuffers() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChunksDiscarded kChunksDiscarded() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PatchesDiscarded kPatchesDiscarded() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InvalidPackets kInvalidPackets() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FilterStats kFilterStats() { return {}; }
+  template <typename T = TraceStats_FilterStats> T* set_filter_stats() {
+    return BeginNestedMessage<T>(11);
+  }
+
+};
+
+class TraceStats_FilterStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ 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(); }
+};
+
+class TraceStats_FilterStats : public ::protozero::Message {
+ public:
+  using Decoder = TraceStats_FilterStats_Decoder;
+  enum : int32_t {
+    kInputPacketsFieldNumber = 1,
+    kInputBytesFieldNumber = 2,
+    kOutputBytesFieldNumber = 3,
+    kErrorsFieldNumber = 4,
+  };
+
+  using FieldMetadata_InputPackets =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_FilterStats>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InputPackets kInputPackets() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InputBytes kInputBytes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OutputBytes kOutputBytes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Errors kErrors() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_BufferSize =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BufferSize kBufferSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BytesWritten kBytesWritten() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BytesOverwritten kBytesOverwritten() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BytesRead kBytesRead() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PaddingBytesWritten kPaddingBytesWritten() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PaddingBytesCleared kPaddingBytesCleared() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChunksWritten kChunksWritten() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChunksRewritten kChunksRewritten() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChunksOverwritten kChunksOverwritten() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChunksDiscarded kChunksDiscarded() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChunksRead kChunksRead() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChunksCommittedOutOfOrder kChunksCommittedOutOfOrder() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WriteWrapCount kWriteWrapCount() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PatchesSucceeded kPatchesSucceeded() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PatchesFailed kPatchesFailed() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReadaheadsSucceeded kReadaheadsSucceeded() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReadaheadsFailed kReadaheadsFailed() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AbiViolations kAbiViolations() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceWriterPacketLoss kTraceWriterPacketLoss() { return {}; }
+  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 {
+
+enum ObservableEvents_Type : int32_t;
+
+class TracingServiceCapabilities_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*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(); }
+};
+
+class TracingServiceCapabilities : public ::protozero::Message {
+ public:
+  using Decoder = TracingServiceCapabilities_Decoder;
+  enum : int32_t {
+    kHasQueryCapabilitiesFieldNumber = 1,
+    kObservableEventsFieldNumber = 2,
+    kHasTraceConfigOutputPathFieldNumber = 3,
+  };
+
+  using FieldMetadata_HasQueryCapabilities =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceCapabilities>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HasQueryCapabilities kHasQueryCapabilities() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ObservableEvents kObservableEvents() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HasTraceConfigOutputPath kHasTraceConfigOutputPath() { return {}; }
+  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);
+  }
+};
+
+} // 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_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*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_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,
+    kNumSessionsFieldNumber = 3,
+    kNumSessionsStartedFieldNumber = 4,
+    kTracingServiceVersionFieldNumber = 5,
+  };
+  using Producer = ::perfetto::protos::pbzero::TracingServiceState_Producer;
+  using DataSource = ::perfetto::protos::pbzero::TracingServiceState_DataSource;
+
+  using FieldMetadata_Producers =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TracingServiceState_Producer,
+      TracingServiceState>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Producers kProducers() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DataSources kDataSources() { return {}; }
+  template <typename T = TracingServiceState_DataSource> T* add_data_sources() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_NumSessions =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingServiceState>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NumSessions kNumSessions() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NumSessionsStarted kNumSessionsStarted() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TracingServiceVersion kTracingServiceVersion() { return {}; }
+  void set_tracing_service_version(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TracingServiceVersion::kFieldId, data, 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_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,
+  };
+
+  using FieldMetadata_DsDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DataSourceDescriptor,
+      TracingServiceState_DataSource>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DsDescriptor kDsDescriptor() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProducerId kProducerId() { return {}; }
+  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=*/4, /*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_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,
+    kUidFieldNumber = 3,
+    kSdkVersionFieldNumber = 4,
+  };
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingServiceState_Producer>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Id kId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingServiceState_Producer>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Uid kUid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SdkVersion kSdkVersion() { return {}; }
+  void set_sdk_version(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SdkVersion::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_AvailableCategories =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrackEventCategory,
+      TrackEventDescriptor>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AvailableCategories kAvailableCategories() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEventCategory>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Description kDescription() { return {}; }
+  void set_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Description::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tags kTags() { return {}; }
+  void add_tags(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tags::kFieldId, data, 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/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 TrackEventConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDisabledCategoriesFieldNumber = 1,
+    kEnabledCategoriesFieldNumber = 2,
+    kDisabledTagsFieldNumber = 3,
+    kEnabledTagsFieldNumber = 4,
+  };
+
+  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(); }
+
+ 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_;
+
+  // 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_TRACK_EVENT_TRACK_EVENT_CONFIG_PROTO_CPP_H_
+// 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,
+  };
+
+  using FieldMetadata_LogIds =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::AndroidLogId,
+      AndroidLogConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LogIds kLogIds() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MinPrio kMinPrio() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FilterTags kFilterTags() { return {}; }
+  void add_filter_tags(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FilterTags::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_PollMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidPolledStateConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PollMs kPollMs() { return {}; }
+  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/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,
+  };
+
+  using FieldMetadata_PackageNameFilter =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PackagesListConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PackageNameFilter kPackageNameFilter() { return {}; }
+  void add_package_name_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_PackageNameFilter::kFieldId, data, 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/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_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/14, /*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_symbolize_ksyms() const { return at<13>().valid(); }
+  bool symbolize_ksyms() const { return at<13>().as_bool(); }
+  bool has_initialize_ksyms_synchronously_for_testing() const { return at<14>().valid(); }
+  bool initialize_ksyms_synchronously_for_testing() const { return at<14>().as_bool(); }
+};
+
+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,
+    kSymbolizeKsymsFieldNumber = 13,
+    kInitializeKsymsSynchronouslyForTestingFieldNumber = 14,
+  };
+  using CompactSchedConfig = ::perfetto::protos::pbzero::FtraceConfig_CompactSchedConfig;
+
+  using FieldMetadata_FtraceEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FtraceEvents kFtraceEvents() { return {}; }
+  void add_ftrace_events(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FtraceEvents::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AtraceCategories kAtraceCategories() { return {}; }
+  void add_atrace_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_AtraceCategories::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AtraceApps kAtraceApps() { return {}; }
+  void add_atrace_apps(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_AtraceApps::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BufferSizeKb kBufferSizeKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DrainPeriodMs kDrainPeriodMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CompactSched kCompactSched() { return {}; }
+  template <typename T = FtraceConfig_CompactSchedConfig> T* set_compact_sched() {
+    return BeginNestedMessage<T>(12);
+  }
+
+
+  using FieldMetadata_SymbolizeKsyms =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SymbolizeKsyms kSymbolizeKsyms() { return {}; }
+  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_InitializeKsymsSynchronouslyForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InitializeKsymsSynchronouslyForTesting kInitializeKsymsSynchronouslyForTesting() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_Enabled =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig_CompactSchedConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Enabled kEnabled() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_CounterPeriodNs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuCounterConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CounterPeriodNs kCounterPeriodNs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CounterIds kCounterIds() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InstrumentedSampling kInstrumentedSampling() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FixGpuClock kFixGpuClock() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_TrackDriverMemoryUsage =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      VulkanMemoryConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrackDriverMemoryUsage kTrackDriverMemoryUsage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrackDeviceMemoryUsage kTrackDeviceMemoryUsage() { return {}; }
+  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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ScanIntervalMs kScanIntervalMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ScanDelayMs kScanDelayMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ScanBatchSize kScanBatchSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DoNotScan kDoNotScan() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ScanMountPoints kScanMountPoints() { return {}; }
+  void add_scan_mount_points(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ScanMountPoints::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MountPointMapping kMountPointMapping() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Mountpoint =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InodeFileConfig_MountPointMappingEntry>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mountpoint kMountpoint() { return {}; }
+  void set_mountpoint(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Mountpoint::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ScanRoots kScanRoots() { return {}; }
+  void add_scan_roots(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ScanRoots::kFieldId, data, 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 {
+
+enum ConsoleConfig_Output : int32_t;
+
+enum ConsoleConfig_Output : int32_t {
+  ConsoleConfig_Output_OUTPUT_UNSPECIFIED = 0,
+  ConsoleConfig_Output_OUTPUT_STDOUT = 1,
+  ConsoleConfig_Output_OUTPUT_STDERR = 2,
+};
+
+const ConsoleConfig_Output ConsoleConfig_Output_MIN = ConsoleConfig_Output_OUTPUT_UNSPECIFIED;
+const ConsoleConfig_Output ConsoleConfig_Output_MAX = ConsoleConfig_Output_OUTPUT_STDERR;
+
+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,
+  };
+  using Output = ::perfetto::protos::pbzero::ConsoleConfig_Output;
+  static const Output OUTPUT_UNSPECIFIED = ConsoleConfig_Output_OUTPUT_UNSPECIFIED;
+  static const Output OUTPUT_STDOUT = ConsoleConfig_Output_OUTPUT_STDOUT;
+  static const Output OUTPUT_STDERR = ConsoleConfig_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Output kOutput() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EnableColors kEnableColors() { return {}; }
+  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 {
+
+enum AndroidPowerConfig_BatteryCounters : int32_t;
+
+enum AndroidPowerConfig_BatteryCounters : int32_t {
+  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,
+};
+
+const AndroidPowerConfig_BatteryCounters AndroidPowerConfig_BatteryCounters_MIN = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED;
+const AndroidPowerConfig_BatteryCounters AndroidPowerConfig_BatteryCounters_MAX = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT_AVG;
+
+class AndroidPowerConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*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(); }
+};
+
+class AndroidPowerConfig : public ::protozero::Message {
+ public:
+  using Decoder = AndroidPowerConfig_Decoder;
+  enum : int32_t {
+    kBatteryPollMsFieldNumber = 1,
+    kBatteryCountersFieldNumber = 2,
+    kCollectPowerRailsFieldNumber = 3,
+    kCollectEnergyEstimationBreakdownFieldNumber = 4,
+  };
+  using BatteryCounters = ::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters;
+  static const BatteryCounters BATTERY_COUNTER_UNSPECIFIED = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED;
+  static const BatteryCounters BATTERY_COUNTER_CHARGE = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CHARGE;
+  static const BatteryCounters BATTERY_COUNTER_CAPACITY_PERCENT = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CAPACITY_PERCENT;
+  static const BatteryCounters BATTERY_COUNTER_CURRENT = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT;
+  static const BatteryCounters BATTERY_COUNTER_CURRENT_AVG = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT_AVG;
+
+  using FieldMetadata_BatteryPollMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidPowerConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BatteryPollMs kBatteryPollMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BatteryCounters kBatteryCounters() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CollectPowerRails kCollectPowerRails() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CollectEnergyEstimationBreakdown kCollectEnergyEstimationBreakdown() { return {}; }
+  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);
+  }
+};
+
+} // 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 {
+
+enum ProcessStatsConfig_Quirks : int32_t;
+
+enum ProcessStatsConfig_Quirks : int32_t {
+  ProcessStatsConfig_Quirks_QUIRKS_UNSPECIFIED = 0,
+  ProcessStatsConfig_Quirks_DISABLE_INITIAL_DUMP = 1,
+  ProcessStatsConfig_Quirks_DISABLE_ON_DEMAND = 2,
+};
+
+const ProcessStatsConfig_Quirks ProcessStatsConfig_Quirks_MIN = ProcessStatsConfig_Quirks_QUIRKS_UNSPECIFIED;
+const ProcessStatsConfig_Quirks ProcessStatsConfig_Quirks_MAX = ProcessStatsConfig_Quirks_DISABLE_ON_DEMAND;
+
+class ProcessStatsConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*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_record_thread_time_in_state() const { return at<7>().valid(); }
+  bool record_thread_time_in_state() const { return at<7>().as_bool(); }
+  bool has_thread_time_in_state_cache_size() const { return at<8>().valid(); }
+  uint32_t thread_time_in_state_cache_size() const { return at<8>().as_uint32(); }
+};
+
+class ProcessStatsConfig : public ::protozero::Message {
+ public:
+  using Decoder = ProcessStatsConfig_Decoder;
+  enum : int32_t {
+    kQuirksFieldNumber = 1,
+    kScanAllProcessesOnStartFieldNumber = 2,
+    kRecordThreadNamesFieldNumber = 3,
+    kProcStatsPollMsFieldNumber = 4,
+    kProcStatsCacheTtlMsFieldNumber = 6,
+    kRecordThreadTimeInStateFieldNumber = 7,
+    kThreadTimeInStateCacheSizeFieldNumber = 8,
+  };
+  using Quirks = ::perfetto::protos::pbzero::ProcessStatsConfig_Quirks;
+  static const Quirks QUIRKS_UNSPECIFIED = ProcessStatsConfig_Quirks_QUIRKS_UNSPECIFIED;
+  static const Quirks DISABLE_INITIAL_DUMP = ProcessStatsConfig_Quirks_DISABLE_INITIAL_DUMP;
+  static const Quirks DISABLE_ON_DEMAND = ProcessStatsConfig_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Quirks kQuirks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ScanAllProcessesOnStart kScanAllProcessesOnStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RecordThreadNames kRecordThreadNames() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcStatsPollMs kProcStatsPollMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcStatsCacheTtlMs kProcStatsCacheTtlMs() { return {}; }
+  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_RecordThreadTimeInState =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProcessStatsConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RecordThreadTimeInState kRecordThreadTimeInState() { return {}; }
+  void set_record_thread_time_in_state(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_RecordThreadTimeInState::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_ThreadTimeInStateCacheSize =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ProcessStatsConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadTimeInStateCacheSize kThreadTimeInStateCacheSize() { return {}; }
+  void set_thread_time_in_state_cache_size(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadTimeInStateCacheSize::kFieldId;
+    // Call the appropriate protozero::Message::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/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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SamplingIntervalBytes kSamplingIntervalBytes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AdaptiveSamplingShmemThreshold kAdaptiveSamplingShmemThreshold() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AdaptiveSamplingMaxSamplingIntervalBytes kAdaptiveSamplingMaxSamplingIntervalBytes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessCmdline kProcessCmdline() { return {}; }
+  void add_process_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProcessCmdline::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TargetInstalledBy kTargetInstalledBy() { return {}; }
+  void add_target_installed_by(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TargetInstalledBy::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Heaps kHeaps() { return {}; }
+  void add_heaps(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Heaps::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExcludeHeaps kExcludeHeaps() { return {}; }
+  void add_exclude_heaps(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ExcludeHeaps::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StreamAllocations kStreamAllocations() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HeapSamplingIntervals kHeapSamplingIntervals() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllHeaps kAllHeaps() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_All kAll() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MinAnonymousMemoryKb kMinAnonymousMemoryKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MaxHeapprofdMemoryKb kMaxHeapprofdMemoryKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MaxHeapprofdCpuSecs kMaxHeapprofdCpuSecs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SkipSymbolPrefix kSkipSymbolPrefix() { return {}; }
+  void add_skip_symbol_prefix(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SkipSymbolPrefix::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ContinuousDumpConfig kContinuousDumpConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ShmemSizeBytes kShmemSizeBytes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockClient kBlockClient() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockClientTimeoutUs kBlockClientTimeoutUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NoStartup kNoStartup() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NoRunning kNoRunning() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DumpAtMax kDumpAtMax() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DisableForkTeardown kDisableForkTeardown() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DisableVforkDetection kDisableVforkDetection() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_DumpPhaseMs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      HeapprofdConfig_ContinuousDumpConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DumpPhaseMs kDumpPhaseMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DumpIntervalMs kDumpIntervalMs() { return {}; }
+  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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessCmdline kProcessCmdline() { return {}; }
+  void add_process_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProcessCmdline::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TargetInstalledBy kTargetInstalledBy() { return {}; }
+  void add_target_installed_by(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TargetInstalledBy::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ContinuousDumpConfig kContinuousDumpConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MinAnonymousMemoryKb kMinAnonymousMemoryKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DumpSmaps kDumpSmaps() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IgnoredTypes kIgnoredTypes() { return {}; }
+  void add_ignored_types(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_IgnoredTypes::kFieldId, data, 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=*/2, /*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(); }
+};
+
+class JavaHprofConfig_ContinuousDumpConfig : public ::protozero::Message {
+ public:
+  using Decoder = JavaHprofConfig_ContinuousDumpConfig_Decoder;
+  enum : int32_t {
+    kDumpPhaseMsFieldNumber = 1,
+    kDumpIntervalMsFieldNumber = 2,
+  };
+
+  using FieldMetadata_DumpPhaseMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      JavaHprofConfig_ContinuousDumpConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DumpPhaseMs kDumpPhaseMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DumpIntervalMs kDumpIntervalMs() { return {}; }
+  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/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;
+
+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,
+  };
+  using CallstackSampling = ::perfetto::protos::pbzero::PerfEventConfig_CallstackSampling;
+  using Scope = ::perfetto::protos::pbzero::PerfEventConfig_Scope;
+
+  using FieldMetadata_Timebase =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfEvents_Timebase,
+      PerfEventConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Timebase kTimebase() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CallstackSampling kCallstackSampling() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RingBufferReadPeriodMs kRingBufferReadPeriodMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RingBufferPages kRingBufferPages() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MaxEnqueuedFootprintKb kMaxEnqueuedFootprintKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MaxDaemonMemoryKb kMaxDaemonMemoryKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RemoteDescriptorTimeoutMs kRemoteDescriptorTimeoutMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UnwindStateClearPeriodMs kUnwindStateClearPeriodMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TargetInstalledBy kTargetInstalledBy() { return {}; }
+  void add_target_installed_by(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TargetInstalledBy::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllCpus kAllCpus() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SamplingFrequency kSamplingFrequency() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_KernelFrames kKernelFrames() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TargetPid kTargetPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TargetCmdline kTargetCmdline() { return {}; }
+  void add_target_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TargetCmdline::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExcludePid kExcludePid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExcludeCmdline kExcludeCmdline() { return {}; }
+  void add_exclude_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ExcludeCmdline::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AdditionalCmdlineCount kAdditionalCmdlineCount() { return {}; }
+  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=*/5, /*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(); }
+};
+
+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,
+  };
+
+  using FieldMetadata_TargetPid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      PerfEventConfig_Scope>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TargetPid kTargetPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TargetCmdline kTargetCmdline() { return {}; }
+  void add_target_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TargetCmdline::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExcludePid kExcludePid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExcludeCmdline kExcludeCmdline() { return {}; }
+  void add_exclude_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ExcludeCmdline::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AdditionalCmdlineCount kAdditionalCmdlineCount() { return {}; }
+  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_CallstackSampling_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*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(); }
+};
+
+class PerfEventConfig_CallstackSampling : public ::protozero::Message {
+ public:
+  using Decoder = PerfEventConfig_CallstackSampling_Decoder;
+  enum : int32_t {
+    kScopeFieldNumber = 1,
+    kKernelFramesFieldNumber = 2,
+  };
+
+  using FieldMetadata_Scope =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfEventConfig_Scope,
+      PerfEventConfig_CallstackSampling>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Scope kScope() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_KernelFrames kKernelFrames() { return {}; }
+  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);
+  }
+};
+
+} // 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;
+enum SysStatsConfig_StatCounters : int32_t;
+enum VmstatCounters : int32_t;
+
+enum SysStatsConfig_StatCounters : int32_t {
+  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,
+};
+
+const SysStatsConfig_StatCounters SysStatsConfig_StatCounters_MIN = SysStatsConfig_StatCounters_STAT_UNSPECIFIED;
+const SysStatsConfig_StatCounters SysStatsConfig_StatCounters_MAX = SysStatsConfig_StatCounters_STAT_FORK_COUNT;
+
+class SysStatsConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*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(); }
+};
+
+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,
+  };
+  using StatCounters = ::perfetto::protos::pbzero::SysStatsConfig_StatCounters;
+  static const StatCounters STAT_UNSPECIFIED = SysStatsConfig_StatCounters_STAT_UNSPECIFIED;
+  static const StatCounters STAT_CPU_TIMES = SysStatsConfig_StatCounters_STAT_CPU_TIMES;
+  static const StatCounters STAT_IRQ_COUNTS = SysStatsConfig_StatCounters_STAT_IRQ_COUNTS;
+  static const StatCounters STAT_SOFTIRQ_COUNTS = SysStatsConfig_StatCounters_STAT_SOFTIRQ_COUNTS;
+  static const StatCounters STAT_FORK_COUNT = SysStatsConfig_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MeminfoPeriodMs kMeminfoPeriodMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MeminfoCounters kMeminfoCounters() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VmstatPeriodMs kVmstatPeriodMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VmstatCounters kVmstatCounters() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StatPeriodMs kStatPeriodMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StatCounters kStatCounters() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DevfreqPeriodMs kDevfreqPeriodMs() { return {}; }
+  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);
+  }
+};
+
+} // 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=*/4, /*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); }
+};
+
+class TrackEventConfig : public ::protozero::Message {
+ public:
+  using Decoder = TrackEventConfig_Decoder;
+  enum : int32_t {
+    kDisabledCategoriesFieldNumber = 1,
+    kEnabledCategoriesFieldNumber = 2,
+    kDisabledTagsFieldNumber = 3,
+    kEnabledTagsFieldNumber = 4,
+  };
+
+  using FieldMetadata_DisabledCategories =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEventConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DisabledCategories kDisabledCategories() { return {}; }
+  void add_disabled_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DisabledCategories::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EnabledCategories kEnabledCategories() { return {}; }
+  void add_enabled_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EnabledCategories::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DisabledTags kDisabledTags() { return {}; }
+  void add_disabled_tags(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DisabledTags::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EnabledTags kEnabledTags() { return {}; }
+  void add_enabled_tags(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EnabledTags::kFieldId, data, 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);
+  }
+};
+
+} // 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 {
+
+enum ChromeConfig_ClientPriority : int32_t;
+
+enum ChromeConfig_ClientPriority : int32_t {
+  ChromeConfig_ClientPriority_UNKNOWN = 0,
+  ChromeConfig_ClientPriority_BACKGROUND = 1,
+  ChromeConfig_ClientPriority_USER_INITIATED = 2,
+};
+
+const ChromeConfig_ClientPriority ChromeConfig_ClientPriority_MIN = ChromeConfig_ClientPriority_UNKNOWN;
+const ChromeConfig_ClientPriority ChromeConfig_ClientPriority_MAX = ChromeConfig_ClientPriority_USER_INITIATED;
+
+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,
+  };
+  using ClientPriority = ::perfetto::protos::pbzero::ChromeConfig_ClientPriority;
+  static const ClientPriority UNKNOWN = ChromeConfig_ClientPriority_UNKNOWN;
+  static const ClientPriority BACKGROUND = ChromeConfig_ClientPriority_BACKGROUND;
+  static const ClientPriority USER_INITIATED = ChromeConfig_ClientPriority_USER_INITIATED;
+
+  using FieldMetadata_TraceConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceConfig kTraceConfig() { return {}; }
+  void set_trace_config(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TraceConfig::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PrivacyFilteringEnabled kPrivacyFilteringEnabled() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ConvertToLegacyJson kConvertToLegacyJson() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClientPriority kClientPriority() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_JsonAgentLabelFilter kJsonAgentLabelFilter() { return {}; }
+  void set_json_agent_label_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_JsonAgentLabelFilter::kFieldId, data, 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/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 AndroidLogConfig;
+class AndroidPolledStateConfig;
+class AndroidPowerConfig;
+class ChromeConfig;
+class FtraceConfig;
+class GpuCounterConfig;
+class HeapprofdConfig;
+class InodeFileConfig;
+class InterceptorConfig;
+class JavaHprofConfig;
+class PackagesListConfig;
+class PerfEventConfig;
+class ProcessStatsConfig;
+class SysStatsConfig;
+class TestConfig;
+class TrackEventConfig;
+class VulkanMemoryConfig;
+enum DataSourceConfig_SessionInitiator : int32_t;
+
+enum DataSourceConfig_SessionInitiator : int32_t {
+  DataSourceConfig_SessionInitiator_SESSION_INITIATOR_UNSPECIFIED = 0,
+  DataSourceConfig_SessionInitiator_SESSION_INITIATOR_TRUSTED_SYSTEM = 1,
+};
+
+const DataSourceConfig_SessionInitiator DataSourceConfig_SessionInitiator_MIN = DataSourceConfig_SessionInitiator_SESSION_INITIATOR_UNSPECIFIED;
+const DataSourceConfig_SessionInitiator DataSourceConfig_SessionInitiator_MAX = DataSourceConfig_SessionInitiator_SESSION_INITIATOR_TRUSTED_SYSTEM;
+
+class DataSourceConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/115, /*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_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_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_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(); }
+  // 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,
+    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,
+    kPackagesListConfigFieldNumber = 109,
+    kPerfEventConfigFieldNumber = 111,
+    kVulkanMemoryConfigFieldNumber = 112,
+    kTrackEventConfigFieldNumber = 113,
+    kAndroidPolledStateConfigFieldNumber = 114,
+    kChromeConfigFieldNumber = 101,
+    kInterceptorConfigFieldNumber = 115,
+    kLegacyConfigFieldNumber = 1000,
+    kForTestingFieldNumber = 1001,
+  };
+  using SessionInitiator = ::perfetto::protos::pbzero::DataSourceConfig_SessionInitiator;
+  static const SessionInitiator SESSION_INITIATOR_UNSPECIFIED = DataSourceConfig_SessionInitiator_SESSION_INITIATOR_UNSPECIFIED;
+  static const SessionInitiator SESSION_INITIATOR_TRUSTED_SYSTEM = DataSourceConfig_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TargetBuffer kTargetBuffer() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceDurationMs kTraceDurationMs() { return {}; }
+  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_StopTimeoutMs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DataSourceConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StopTimeoutMs kStopTimeoutMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EnableExtraGuardrails kEnableExtraGuardrails() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SessionInitiator kSessionInitiator() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TracingSessionId kTracingSessionId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FtraceConfig kFtraceConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InodeFileConfig kInodeFileConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessStatsConfig kProcessStatsConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SysStatsConfig kSysStatsConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HeapprofdConfig kHeapprofdConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_JavaHprofConfig kJavaHprofConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AndroidPowerConfig kAndroidPowerConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AndroidLogConfig kAndroidLogConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuCounterConfig kGpuCounterConfig() { return {}; }
+  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_PackagesListConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      109,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PackagesListConfig,
+      DataSourceConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PackagesListConfig kPackagesListConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PerfEventConfig kPerfEventConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VulkanMemoryConfig kVulkanMemoryConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrackEventConfig kTrackEventConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AndroidPolledStateConfig kAndroidPolledStateConfig() { return {}; }
+  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_ChromeConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      101,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeConfig,
+      DataSourceConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeConfig kChromeConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InterceptorConfig kInterceptorConfig() { return {}; }
+  template <typename T = InterceptorConfig> T* set_interceptor_config() {
+    return BeginNestedMessage<T>(115);
+  }
+
+
+  using FieldMetadata_LegacyConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      1000,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DataSourceConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LegacyConfig kLegacyConfig() { return {}; }
+  void set_legacy_config(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LegacyConfig::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ForTesting kForTesting() { return {}; }
+  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/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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InterceptorConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ConsoleConfig kConsoleConfig() { return {}; }
+  template <typename T = ConsoleConfig> T* set_console_config() {
+    return BeginNestedMessage<T>(100);
+  }
+
+  void set_console_config_raw(const std::string& raw) {
+    return AppendBytes(100, raw.data(), raw.size());
+  }
+
+};
+
+} // 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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceConfig kTraceConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ShmemSizeKb kShmemSizeKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ShmemPageSizeKb kShmemPageSizeKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NumProcesses kNumProcesses() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NumThreads kNumThreads() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MaxEvents kMaxEvents() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nesting kNesting() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SteadyStateTimings kSteadyStateTimings() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BurstPeriodMs kBurstPeriodMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BurstDurationMs kBurstDurationMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BurstTimings kBurstTimings() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_PayloadMean =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      StressTestConfig_WriterTiming>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PayloadMean kPayloadMean() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PayloadStddev kPayloadStddev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RateMean kRateMean() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RateStddev kRateStddev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PayloadWriteTimeMs kPayloadWriteTimeMs() { return {}; }
+  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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MessageCount kMessageCount() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MaxMessagesPerSecond kMaxMessagesPerSecond() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Seed kSeed() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MessageSize kMessageSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SendBatchOnRegister kSendBatchOnRegister() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DummyFields kDummyFields() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_FieldUint32 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TestConfig_DummyFields>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FieldUint32 kFieldUint32() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FieldInt32 kFieldInt32() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FieldUint64 kFieldUint64() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FieldInt64 kFieldInt64() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FieldFixed64 kFieldFixed64() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FieldSfixed64 kFieldSfixed64() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FieldFixed32 kFieldFixed32() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FieldSfixed32 kFieldSfixed32() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FieldDouble kFieldDouble() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FieldFloat kFieldFloat() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FieldSint64 kFieldSint64() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FieldSint32 kFieldSint32() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FieldString kFieldString() { return {}; }
+  void set_field_string(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FieldString::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FieldBytes kFieldBytes() { return {}; }
+  void set_field_bytes(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_FieldBytes::kFieldId, data, 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_BufferConfig;
+class TraceConfig_BuiltinDataSource;
+class TraceConfig_DataSource;
+class TraceConfig_GuardrailOverrides;
+class TraceConfig_IncidentReportConfig;
+class TraceConfig_IncrementalStateConfig;
+class TraceConfig_ProducerConfig;
+class TraceConfig_StatsdMetadata;
+class TraceConfig_TraceFilter;
+class TraceConfig_TriggerConfig;
+class TraceConfig_TriggerConfig_Trigger;
+enum BuiltinClock : int32_t;
+enum TraceConfig_BufferConfig_FillPolicy : int32_t;
+enum TraceConfig_CompressionType : int32_t;
+enum TraceConfig_LockdownModeOperation : int32_t;
+enum TraceConfig_StatsdLogging : int32_t;
+enum TraceConfig_TriggerConfig_TriggerMode : int32_t;
+
+enum TraceConfig_LockdownModeOperation : int32_t {
+  TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED = 0,
+  TraceConfig_LockdownModeOperation_LOCKDOWN_CLEAR = 1,
+  TraceConfig_LockdownModeOperation_LOCKDOWN_SET = 2,
+};
+
+const TraceConfig_LockdownModeOperation TraceConfig_LockdownModeOperation_MIN = TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED;
+const TraceConfig_LockdownModeOperation TraceConfig_LockdownModeOperation_MAX = TraceConfig_LockdownModeOperation_LOCKDOWN_SET;
+
+enum TraceConfig_CompressionType : int32_t {
+  TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED = 0,
+  TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE = 1,
+};
+
+const TraceConfig_CompressionType TraceConfig_CompressionType_MIN = TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED;
+const TraceConfig_CompressionType TraceConfig_CompressionType_MAX = TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE;
+
+enum TraceConfig_StatsdLogging : int32_t {
+  TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED = 0,
+  TraceConfig_StatsdLogging_STATSD_LOGGING_ENABLED = 1,
+  TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED = 2,
+};
+
+const TraceConfig_StatsdLogging TraceConfig_StatsdLogging_MIN = TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED;
+const TraceConfig_StatsdLogging TraceConfig_StatsdLogging_MAX = TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED;
+
+enum TraceConfig_TriggerConfig_TriggerMode : int32_t {
+  TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED = 0,
+  TraceConfig_TriggerConfig_TriggerMode_START_TRACING = 1,
+  TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING = 2,
+};
+
+const TraceConfig_TriggerConfig_TriggerMode TraceConfig_TriggerConfig_TriggerMode_MIN = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
+const TraceConfig_TriggerConfig_TriggerMode TraceConfig_TriggerConfig_TriggerMode_MAX = TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING;
+
+enum TraceConfig_BufferConfig_FillPolicy : int32_t {
+  TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED = 0,
+  TraceConfig_BufferConfig_FillPolicy_RING_BUFFER = 1,
+  TraceConfig_BufferConfig_FillPolicy_DISCARD = 2,
+};
+
+const TraceConfig_BufferConfig_FillPolicy TraceConfig_BufferConfig_FillPolicy_MIN = TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED;
+const TraceConfig_BufferConfig_FillPolicy TraceConfig_BufferConfig_FillPolicy_MAX = TraceConfig_BufferConfig_FillPolicy_DISCARD;
+
+class TraceConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/32, /*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_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_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<32>().valid(); }
+  ::protozero::ConstBytes trace_filter() const { return at<32>().as_bytes(); }
+};
+
+class TraceConfig : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_Decoder;
+  enum : int32_t {
+    kBuffersFieldNumber = 1,
+    kDataSourcesFieldNumber = 2,
+    kBuiltinDataSourcesFieldNumber = 20,
+    kDurationMsFieldNumber = 3,
+    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,
+    kIncidentReportConfigFieldNumber = 25,
+    kStatsdLoggingFieldNumber = 31,
+    kTraceUuidMsbFieldNumber = 27,
+    kTraceUuidLsbFieldNumber = 28,
+    kTraceFilterFieldNumber = 32,
+  };
+  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 LockdownModeOperation = ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation;
+  using CompressionType = ::perfetto::protos::pbzero::TraceConfig_CompressionType;
+  using StatsdLogging = ::perfetto::protos::pbzero::TraceConfig_StatsdLogging;
+  static const LockdownModeOperation LOCKDOWN_UNCHANGED = TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED;
+  static const LockdownModeOperation LOCKDOWN_CLEAR = TraceConfig_LockdownModeOperation_LOCKDOWN_CLEAR;
+  static const LockdownModeOperation LOCKDOWN_SET = TraceConfig_LockdownModeOperation_LOCKDOWN_SET;
+  static const CompressionType COMPRESSION_TYPE_UNSPECIFIED = TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED;
+  static const CompressionType COMPRESSION_TYPE_DEFLATE = TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE;
+  static const StatsdLogging STATSD_LOGGING_UNSPECIFIED = TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED;
+  static const StatsdLogging STATSD_LOGGING_ENABLED = TraceConfig_StatsdLogging_STATSD_LOGGING_ENABLED;
+  static const StatsdLogging STATSD_LOGGING_DISABLED = TraceConfig_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Buffers kBuffers() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DataSources kDataSources() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BuiltinDataSources kBuiltinDataSources() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DurationMs kDurationMs() { return {}; }
+  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_EnableExtraGuardrails =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EnableExtraGuardrails kEnableExtraGuardrails() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LockdownMode kLockdownMode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Producers kProducers() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StatsdMetadata kStatsdMetadata() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WriteIntoFile kWriteIntoFile() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OutputPath kOutputPath() { return {}; }
+  void set_output_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_OutputPath::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FileWritePeriodMs kFileWritePeriodMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MaxFileSizeBytes kMaxFileSizeBytes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GuardrailOverrides kGuardrailOverrides() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DeferredStart kDeferredStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FlushPeriodMs kFlushPeriodMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FlushTimeoutMs kFlushTimeoutMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DataSourceStopTimeoutMs kDataSourceStopTimeoutMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NotifyTraceur kNotifyTraceur() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BugreportScore kBugreportScore() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TriggerConfig kTriggerConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ActivateTriggers kActivateTriggers() { return {}; }
+  void add_activate_triggers(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ActivateTriggers::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IncrementalStateConfig kIncrementalStateConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllowUserBuildTracing kAllowUserBuildTracing() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UniqueSessionName kUniqueSessionName() { return {}; }
+  void set_unique_session_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_UniqueSessionName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CompressionType kCompressionType() { return {}; }
+  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_IncidentReportConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_IncidentReportConfig,
+      TraceConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IncidentReportConfig kIncidentReportConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StatsdLogging kStatsdLogging() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceUuidMsb kTraceUuidMsb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceUuidLsb kTraceUuidLsb() { return {}; }
+  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<
+      32,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_TraceFilter,
+      TraceConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceFilter kTraceFilter() { return {}; }
+  template <typename T = TraceConfig_TraceFilter> T* set_trace_filter() {
+    return BeginNestedMessage<T>(32);
+  }
+
+};
+
+class TraceConfig_TraceFilter_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*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(); }
+};
+
+class TraceConfig_TraceFilter : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_TraceFilter_Decoder;
+  enum : int32_t {
+    kBytecodeFieldNumber = 1,
+  };
+
+  using FieldMetadata_Bytecode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      TraceConfig_TraceFilter>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Bytecode kBytecode() { return {}; }
+  void set_bytecode(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Bytecode::kFieldId, data, 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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_DestinationPackage =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_IncidentReportConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DestinationPackage kDestinationPackage() { return {}; }
+  void set_destination_package(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DestinationPackage::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DestinationClass kDestinationClass() { return {}; }
+  void set_destination_class(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DestinationClass::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PrivacyLevel kPrivacyLevel() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SkipIncidentd kSkipIncidentd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SkipDropbox kSkipDropbox() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_ClearPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_IncrementalStateConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClearPeriodMs kClearPeriodMs() { return {}; }
+  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=*/3, /*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_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,
+    kTriggersFieldNumber = 2,
+    kTriggerTimeoutMsFieldNumber = 3,
+  };
+  using Trigger = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_Trigger;
+  using TriggerMode = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode;
+  static const TriggerMode UNSPECIFIED = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
+  static const TriggerMode START_TRACING = TraceConfig_TriggerConfig_TriggerMode_START_TRACING;
+  static const TriggerMode STOP_TRACING = TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING;
+
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TriggerMode kTriggerMode() { return {}; }
+  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_Triggers =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_TriggerConfig_Trigger,
+      TraceConfig_TriggerConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Triggers kTriggers() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TriggerTimeoutMs kTriggerTimeoutMs() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_TriggerConfig_Trigger>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProducerNameRegex kProducerNameRegex() { return {}; }
+  void set_producer_name_regex(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerNameRegex::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StopDelayMs kStopDelayMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MaxPer24H kMaxPer24H() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SkipProbability kSkipProbability() { return {}; }
+  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=*/1, /*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(); }
+};
+
+class TraceConfig_GuardrailOverrides : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_GuardrailOverrides_Decoder;
+  enum : int32_t {
+    kMaxUploadPerDayBytesFieldNumber = 1,
+  };
+
+  using FieldMetadata_MaxUploadPerDayBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceConfig_GuardrailOverrides>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MaxUploadPerDayBytes kMaxUploadPerDayBytes() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_TriggeringAlertId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TraceConfig_StatsdMetadata>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TriggeringAlertId kTriggeringAlertId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TriggeringConfigUid kTriggeringConfigUid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TriggeringConfigId kTriggeringConfigId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TriggeringSubscriptionId kTriggeringSubscriptionId() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_ProducerName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_ProducerConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProducerName kProducerName() { return {}; }
+  void set_producer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ShmSizeKb kShmSizeKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PageSizeKb kPageSizeKb() { return {}; }
+  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=*/7, /*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(); }
+};
+
+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,
+  };
+
+  using FieldMetadata_DisableClockSnapshotting =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_BuiltinDataSource>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DisableClockSnapshotting kDisableClockSnapshotting() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DisableTraceConfig kDisableTraceConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DisableSystemInfo kDisableSystemInfo() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DisableServiceEvents kDisableServiceEvents() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PrimaryTraceClock kPrimaryTraceClock() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SnapshotIntervalMs kSnapshotIntervalMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PreferSuspendClockForSnapshot kPreferSuspendClockForSnapshot() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_Config =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DataSourceConfig,
+      TraceConfig_DataSource>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Config kConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProducerNameFilter kProducerNameFilter() { return {}; }
+  void add_producer_name_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerNameFilter::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProducerNameRegexFilter kProducerNameRegexFilter() { return {}; }
+  void add_producer_name_regex_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerNameRegexFilter::kFieldId, data, 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=*/4, /*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(); }
+};
+
+class TraceConfig_BufferConfig : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_BufferConfig_Decoder;
+  enum : int32_t {
+    kSizeKbFieldNumber = 1,
+    kFillPolicyFieldNumber = 4,
+  };
+  using FillPolicy = ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy;
+  static const FillPolicy UNSPECIFIED = TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED;
+  static const FillPolicy RING_BUFFER = TraceConfig_BufferConfig_FillPolicy_RING_BUFFER;
+  static const FillPolicy DISCARD = TraceConfig_BufferConfig_FillPolicy_DISCARD;
+
+  using FieldMetadata_SizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_BufferConfig>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SizeKb kSizeKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FillPolicy kFillPolicy() { return {}; }
+  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);
+  }
+};
+
+} // 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;
+
+enum ClockSnapshot_Clock_BuiltinClocks : int32_t {
+  ClockSnapshot_Clock_BuiltinClocks_UNKNOWN = 0,
+  ClockSnapshot_Clock_BuiltinClocks_REALTIME = 1,
+  ClockSnapshot_Clock_BuiltinClocks_REALTIME_COARSE = 2,
+  ClockSnapshot_Clock_BuiltinClocks_MONOTONIC = 3,
+  ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_COARSE = 4,
+  ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_RAW = 5,
+  ClockSnapshot_Clock_BuiltinClocks_BOOTTIME = 6,
+  ClockSnapshot_Clock_BuiltinClocks_BUILTIN_CLOCK_MAX_ID = 63,
+};
+
+const ClockSnapshot_Clock_BuiltinClocks ClockSnapshot_Clock_BuiltinClocks_MIN = ClockSnapshot_Clock_BuiltinClocks_UNKNOWN;
+const ClockSnapshot_Clock_BuiltinClocks ClockSnapshot_Clock_BuiltinClocks_MAX = ClockSnapshot_Clock_BuiltinClocks_BUILTIN_CLOCK_MAX_ID;
+
+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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Clocks kClocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PrimaryTraceClock kPrimaryTraceClock() { return {}; }
+  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,
+  };
+  using BuiltinClocks = ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks;
+  static const BuiltinClocks UNKNOWN = ClockSnapshot_Clock_BuiltinClocks_UNKNOWN;
+  static const BuiltinClocks REALTIME = ClockSnapshot_Clock_BuiltinClocks_REALTIME;
+  static const BuiltinClocks REALTIME_COARSE = ClockSnapshot_Clock_BuiltinClocks_REALTIME_COARSE;
+  static const BuiltinClocks MONOTONIC = ClockSnapshot_Clock_BuiltinClocks_MONOTONIC;
+  static const BuiltinClocks MONOTONIC_COARSE = ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_COARSE;
+  static const BuiltinClocks MONOTONIC_RAW = ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_RAW;
+  static const BuiltinClocks BOOTTIME = ClockSnapshot_Clock_BuiltinClocks_BOOTTIME;
+  static const BuiltinClocks BUILTIN_CLOCK_MAX_ID = ClockSnapshot_Clock_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClockId kClockId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Timestamp kTimestamp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IsIncremental kIsIncremental() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UnitMultiplierNs kUnitMultiplierNs() { return {}; }
+  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/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,
+  };
+
+  using FieldMetadata_TriggerName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Trigger>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TriggerName kTriggerName() { return {}; }
+  void set_trigger_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TriggerName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProducerName kProducerName() { return {}; }
+  void set_producer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrustedProducerUid kTrustedProducerUid() { return {}; }
+  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=*/4, /*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(); }
+};
+
+class SystemInfo : public ::protozero::Message {
+ public:
+  using Decoder = SystemInfo_Decoder;
+  enum : int32_t {
+    kUtsnameFieldNumber = 1,
+    kAndroidBuildFingerprintFieldNumber = 2,
+    kHzFieldNumber = 3,
+    kTracingServiceVersionFieldNumber = 4,
+  };
+
+  using FieldMetadata_Utsname =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Utsname,
+      SystemInfo>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Utsname kUtsname() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AndroidBuildFingerprint kAndroidBuildFingerprint() { return {}; }
+  void set_android_build_fingerprint(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_AndroidBuildFingerprint::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Hz kHz() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TracingServiceVersion kTracingServiceVersion() { return {}; }
+  void set_tracing_service_version(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TracingServiceVersion::kFieldId, data, 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 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,
+  };
+
+  using FieldMetadata_Sysname =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Utsname>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sysname kSysname() { return {}; }
+  void set_sysname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Sysname::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Version kVersion() { return {}; }
+  void set_version(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Version::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Release kRelease() { return {}; }
+  void set_release(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Release::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Machine kMachine() { return {}; }
+  void set_machine(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Machine::kFieldId, data, 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_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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Events kEvents() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Stats kStats() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_NumTotal =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidLogPacket_Stats>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NumTotal kNumTotal() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NumFailed kNumFailed() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NumSkipped kNumSkipped() { return {}; }
+  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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LogId kLogId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tid kTid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Uid kUid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Timestamp kTimestamp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tag kTag() { return {}; }
+  void set_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Prio kPrio() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Message kMessage() { return {}; }
+  void set_message(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Message::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Args kArgs() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidLogPacket_LogEvent_Arg>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IntValue kIntValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FloatValue kFloatValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StringValue kStringValue() { return {}; }
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, 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/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;
+enum FrameTimelineEvent_PredictionType : int32_t;
+enum FrameTimelineEvent_PresentType : int32_t;
+
+enum FrameTimelineEvent_JankType : int32_t {
+  FrameTimelineEvent_JankType_JANK_UNSPECIFIED = 0,
+  FrameTimelineEvent_JankType_JANK_NONE = 1,
+  FrameTimelineEvent_JankType_JANK_SF_SCHEDULING = 2,
+  FrameTimelineEvent_JankType_JANK_PREDICTION_ERROR = 4,
+  FrameTimelineEvent_JankType_JANK_DISPLAY_HAL = 8,
+  FrameTimelineEvent_JankType_JANK_SF_CPU_DEADLINE_MISSED = 16,
+  FrameTimelineEvent_JankType_JANK_SF_GPU_DEADLINE_MISSED = 32,
+  FrameTimelineEvent_JankType_JANK_APP_DEADLINE_MISSED = 64,
+  FrameTimelineEvent_JankType_JANK_BUFFER_STUFFING = 128,
+  FrameTimelineEvent_JankType_JANK_UNKNOWN = 256,
+  FrameTimelineEvent_JankType_JANK_SF_STUFFING = 512,
+};
+
+const FrameTimelineEvent_JankType FrameTimelineEvent_JankType_MIN = FrameTimelineEvent_JankType_JANK_UNSPECIFIED;
+const FrameTimelineEvent_JankType FrameTimelineEvent_JankType_MAX = FrameTimelineEvent_JankType_JANK_SF_STUFFING;
+
+enum FrameTimelineEvent_PresentType : int32_t {
+  FrameTimelineEvent_PresentType_PRESENT_UNSPECIFIED = 0,
+  FrameTimelineEvent_PresentType_PRESENT_ON_TIME = 1,
+  FrameTimelineEvent_PresentType_PRESENT_LATE = 2,
+  FrameTimelineEvent_PresentType_PRESENT_EARLY = 3,
+  FrameTimelineEvent_PresentType_PRESENT_DROPPED = 4,
+  FrameTimelineEvent_PresentType_PRESENT_UNKNOWN = 5,
+};
+
+const FrameTimelineEvent_PresentType FrameTimelineEvent_PresentType_MIN = FrameTimelineEvent_PresentType_PRESENT_UNSPECIFIED;
+const FrameTimelineEvent_PresentType FrameTimelineEvent_PresentType_MAX = FrameTimelineEvent_PresentType_PRESENT_UNKNOWN;
+
+enum FrameTimelineEvent_PredictionType : int32_t {
+  FrameTimelineEvent_PredictionType_PREDICTION_UNSPECIFIED = 0,
+  FrameTimelineEvent_PredictionType_PREDICTION_VALID = 1,
+  FrameTimelineEvent_PredictionType_PREDICTION_EXPIRED = 2,
+  FrameTimelineEvent_PredictionType_PREDICTION_UNKNOWN = 3,
+};
+
+const FrameTimelineEvent_PredictionType FrameTimelineEvent_PredictionType_MIN = FrameTimelineEvent_PredictionType_PREDICTION_UNSPECIFIED;
+const FrameTimelineEvent_PredictionType FrameTimelineEvent_PredictionType_MAX = FrameTimelineEvent_PredictionType_PREDICTION_UNKNOWN;
+
+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,
+  };
+  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;
+  using PresentType = ::perfetto::protos::pbzero::FrameTimelineEvent_PresentType;
+  using PredictionType = ::perfetto::protos::pbzero::FrameTimelineEvent_PredictionType;
+  static const JankType JANK_UNSPECIFIED = FrameTimelineEvent_JankType_JANK_UNSPECIFIED;
+  static const JankType JANK_NONE = FrameTimelineEvent_JankType_JANK_NONE;
+  static const JankType JANK_SF_SCHEDULING = FrameTimelineEvent_JankType_JANK_SF_SCHEDULING;
+  static const JankType JANK_PREDICTION_ERROR = FrameTimelineEvent_JankType_JANK_PREDICTION_ERROR;
+  static const JankType JANK_DISPLAY_HAL = FrameTimelineEvent_JankType_JANK_DISPLAY_HAL;
+  static const JankType JANK_SF_CPU_DEADLINE_MISSED = FrameTimelineEvent_JankType_JANK_SF_CPU_DEADLINE_MISSED;
+  static const JankType JANK_SF_GPU_DEADLINE_MISSED = FrameTimelineEvent_JankType_JANK_SF_GPU_DEADLINE_MISSED;
+  static const JankType JANK_APP_DEADLINE_MISSED = FrameTimelineEvent_JankType_JANK_APP_DEADLINE_MISSED;
+  static const JankType JANK_BUFFER_STUFFING = FrameTimelineEvent_JankType_JANK_BUFFER_STUFFING;
+  static const JankType JANK_UNKNOWN = FrameTimelineEvent_JankType_JANK_UNKNOWN;
+  static const JankType JANK_SF_STUFFING = FrameTimelineEvent_JankType_JANK_SF_STUFFING;
+  static const PresentType PRESENT_UNSPECIFIED = FrameTimelineEvent_PresentType_PRESENT_UNSPECIFIED;
+  static const PresentType PRESENT_ON_TIME = FrameTimelineEvent_PresentType_PRESENT_ON_TIME;
+  static const PresentType PRESENT_LATE = FrameTimelineEvent_PresentType_PRESENT_LATE;
+  static const PresentType PRESENT_EARLY = FrameTimelineEvent_PresentType_PRESENT_EARLY;
+  static const PresentType PRESENT_DROPPED = FrameTimelineEvent_PresentType_PRESENT_DROPPED;
+  static const PresentType PRESENT_UNKNOWN = FrameTimelineEvent_PresentType_PRESENT_UNKNOWN;
+  static const PredictionType PREDICTION_UNSPECIFIED = FrameTimelineEvent_PredictionType_PREDICTION_UNSPECIFIED;
+  static const PredictionType PREDICTION_VALID = FrameTimelineEvent_PredictionType_PREDICTION_VALID;
+  static const PredictionType PREDICTION_EXPIRED = FrameTimelineEvent_PredictionType_PREDICTION_EXPIRED;
+  static const PredictionType PREDICTION_UNKNOWN = FrameTimelineEvent_PredictionType_PREDICTION_UNKNOWN;
+
+  using FieldMetadata_ExpectedDisplayFrameStart =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FrameTimelineEvent_ExpectedDisplayFrameStart,
+      FrameTimelineEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExpectedDisplayFrameStart kExpectedDisplayFrameStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ActualDisplayFrameStart kActualDisplayFrameStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExpectedSurfaceFrameStart kExpectedSurfaceFrameStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ActualSurfaceFrameStart kActualSurfaceFrameStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FrameEnd kFrameEnd() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Cookie =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_FrameEnd>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cookie kCookie() { return {}; }
+  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=*/8, /*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(); }
+};
+
+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,
+  };
+
+  using FieldMetadata_Cookie =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ActualDisplayFrameStart>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cookie kCookie() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Token kToken() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PresentType kPresentType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OnTimeFinish kOnTimeFinish() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuComposition kGpuComposition() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_JankType kJankType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PredictionType kPredictionType() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_Cookie =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ExpectedDisplayFrameStart>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cookie kCookie() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Token kToken() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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=*/11, /*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(); }
+};
+
+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,
+  };
+
+  using FieldMetadata_Cookie =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cookie kCookie() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Token kToken() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DisplayFrameToken kDisplayFrameToken() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LayerName kLayerName() { return {}; }
+  void set_layer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LayerName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PresentType kPresentType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OnTimeFinish kOnTimeFinish() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuComposition kGpuComposition() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_JankType kJankType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PredictionType kPredictionType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IsBuffer kIsBuffer() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_Cookie =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ExpectedSurfaceFrameStart>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cookie kCookie() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Token kToken() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DisplayFrameToken kDisplayFrameToken() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LayerName kLayerName() { return {}; }
+  void set_layer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LayerName::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_GpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuMemTotalEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuId kGpuId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Size kSize() { return {}; }
+  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;
+enum GraphicsFrameEvent_BufferEventType : int32_t;
+
+enum GraphicsFrameEvent_BufferEventType : int32_t {
+  GraphicsFrameEvent_BufferEventType_UNSPECIFIED = 0,
+  GraphicsFrameEvent_BufferEventType_DEQUEUE = 1,
+  GraphicsFrameEvent_BufferEventType_QUEUE = 2,
+  GraphicsFrameEvent_BufferEventType_POST = 3,
+  GraphicsFrameEvent_BufferEventType_ACQUIRE_FENCE = 4,
+  GraphicsFrameEvent_BufferEventType_LATCH = 5,
+  GraphicsFrameEvent_BufferEventType_HWC_COMPOSITION_QUEUED = 6,
+  GraphicsFrameEvent_BufferEventType_FALLBACK_COMPOSITION = 7,
+  GraphicsFrameEvent_BufferEventType_PRESENT_FENCE = 8,
+  GraphicsFrameEvent_BufferEventType_RELEASE_FENCE = 9,
+  GraphicsFrameEvent_BufferEventType_MODIFY = 10,
+  GraphicsFrameEvent_BufferEventType_DETACH = 11,
+  GraphicsFrameEvent_BufferEventType_ATTACH = 12,
+  GraphicsFrameEvent_BufferEventType_CANCEL = 13,
+};
+
+const GraphicsFrameEvent_BufferEventType GraphicsFrameEvent_BufferEventType_MIN = GraphicsFrameEvent_BufferEventType_UNSPECIFIED;
+const GraphicsFrameEvent_BufferEventType GraphicsFrameEvent_BufferEventType_MAX = GraphicsFrameEvent_BufferEventType_CANCEL;
+
+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,
+  };
+  using BufferEvent = ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEvent;
+  using BufferEventType = ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType;
+  static const BufferEventType UNSPECIFIED = GraphicsFrameEvent_BufferEventType_UNSPECIFIED;
+  static const BufferEventType DEQUEUE = GraphicsFrameEvent_BufferEventType_DEQUEUE;
+  static const BufferEventType QUEUE = GraphicsFrameEvent_BufferEventType_QUEUE;
+  static const BufferEventType POST = GraphicsFrameEvent_BufferEventType_POST;
+  static const BufferEventType ACQUIRE_FENCE = GraphicsFrameEvent_BufferEventType_ACQUIRE_FENCE;
+  static const BufferEventType LATCH = GraphicsFrameEvent_BufferEventType_LATCH;
+  static const BufferEventType HWC_COMPOSITION_QUEUED = GraphicsFrameEvent_BufferEventType_HWC_COMPOSITION_QUEUED;
+  static const BufferEventType FALLBACK_COMPOSITION = GraphicsFrameEvent_BufferEventType_FALLBACK_COMPOSITION;
+  static const BufferEventType PRESENT_FENCE = GraphicsFrameEvent_BufferEventType_PRESENT_FENCE;
+  static const BufferEventType RELEASE_FENCE = GraphicsFrameEvent_BufferEventType_RELEASE_FENCE;
+  static const BufferEventType MODIFY = GraphicsFrameEvent_BufferEventType_MODIFY;
+  static const BufferEventType DETACH = GraphicsFrameEvent_BufferEventType_DETACH;
+  static const BufferEventType ATTACH = GraphicsFrameEvent_BufferEventType_ATTACH;
+  static const BufferEventType CANCEL = GraphicsFrameEvent_BufferEventType_CANCEL;
+
+  using FieldMetadata_BufferEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GraphicsFrameEvent_BufferEvent,
+      GraphicsFrameEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BufferEvent kBufferEvent() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_FrameNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GraphicsFrameEvent_BufferEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FrameNumber kFrameNumber() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LayerName kLayerName() { return {}; }
+  void set_layer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LayerName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DurationNs kDurationNs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BufferId kBufferId() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_DisplayState =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      InitialDisplayState>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DisplayState kDisplayState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Brightness kBrightness() { return {}; }
+  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/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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Packages kPackages() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ParseError kParseError() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReadError kReadError() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PackagesList_PackageInfo>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Uid kUid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Debuggable kDebuggable() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProfileableFromShell kProfileableFromShell() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VersionCode kVersionCode() { return {}; }
+  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/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,
+  };
+
+  using FieldMetadata_BenchmarkStartTimeUs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeBenchmarkMetadata>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BenchmarkStartTimeUs kBenchmarkStartTimeUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StoryRunTimeUs kStoryRunTimeUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BenchmarkName kBenchmarkName() { return {}; }
+  void set_benchmark_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_BenchmarkName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BenchmarkDescription kBenchmarkDescription() { return {}; }
+  void set_benchmark_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_BenchmarkDescription::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Label kLabel() { return {}; }
+  void set_label(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Label::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StoryName kStoryName() { return {}; }
+  void set_story_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StoryName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StoryTags kStoryTags() { return {}; }
+  void add_story_tags(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StoryTags::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StoryRunIndex kStoryRunIndex() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HadFailures kHadFailures() { return {}; }
+  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;
+enum BackgroundTracingMetadata_TriggerRule_NamedRule_EventType : int32_t;
+enum BackgroundTracingMetadata_TriggerRule_TriggerType : int32_t;
+
+enum BackgroundTracingMetadata_TriggerRule_TriggerType : int32_t {
+  BackgroundTracingMetadata_TriggerRule_TriggerType_TRIGGER_UNSPECIFIED = 0,
+  BackgroundTracingMetadata_TriggerRule_TriggerType_MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE = 1,
+  BackgroundTracingMetadata_TriggerRule_TriggerType_MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED = 2,
+};
+
+const BackgroundTracingMetadata_TriggerRule_TriggerType BackgroundTracingMetadata_TriggerRule_TriggerType_MIN = BackgroundTracingMetadata_TriggerRule_TriggerType_TRIGGER_UNSPECIFIED;
+const BackgroundTracingMetadata_TriggerRule_TriggerType BackgroundTracingMetadata_TriggerRule_TriggerType_MAX = BackgroundTracingMetadata_TriggerRule_TriggerType_MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED;
+
+enum BackgroundTracingMetadata_TriggerRule_NamedRule_EventType : int32_t {
+  BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_UNSPECIFIED = 0,
+  BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_SESSION_RESTORE = 1,
+  BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_NAVIGATION = 2,
+  BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_STARTUP = 3,
+  BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_REACHED_CODE = 4,
+  BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_CONTENT_TRIGGER = 5,
+  BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_TEST_RULE = 1000,
+};
+
+const BackgroundTracingMetadata_TriggerRule_NamedRule_EventType BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_MIN = BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_UNSPECIFIED;
+const BackgroundTracingMetadata_TriggerRule_NamedRule_EventType BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_MAX = BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_TEST_RULE;
+
+class BackgroundTracingMetadata_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*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); }
+};
+
+class BackgroundTracingMetadata : public ::protozero::Message {
+ public:
+  using Decoder = BackgroundTracingMetadata_Decoder;
+  enum : int32_t {
+    kTriggeredRuleFieldNumber = 1,
+    kActiveRulesFieldNumber = 2,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TriggeredRule kTriggeredRule() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ActiveRules kActiveRules() { return {}; }
+  template <typename T = BackgroundTracingMetadata_TriggerRule> T* add_active_rules() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class BackgroundTracingMetadata_TriggerRule_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*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(); }
+};
+
+class BackgroundTracingMetadata_TriggerRule : public ::protozero::Message {
+ public:
+  using Decoder = BackgroundTracingMetadata_TriggerRule_Decoder;
+  enum : int32_t {
+    kTriggerTypeFieldNumber = 1,
+    kHistogramRuleFieldNumber = 2,
+    kNamedRuleFieldNumber = 3,
+  };
+  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 const TriggerType TRIGGER_UNSPECIFIED = BackgroundTracingMetadata_TriggerRule_TriggerType_TRIGGER_UNSPECIFIED;
+  static const TriggerType MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE = BackgroundTracingMetadata_TriggerRule_TriggerType_MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE;
+  static const TriggerType MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED = BackgroundTracingMetadata_TriggerRule_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TriggerType kTriggerType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HistogramRule kHistogramRule() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NamedRule kNamedRule() { return {}; }
+  template <typename T = BackgroundTracingMetadata_TriggerRule_NamedRule> T* set_named_rule() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+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,
+  };
+  using EventType = ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType;
+  static const EventType UNSPECIFIED = BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_UNSPECIFIED;
+  static const EventType SESSION_RESTORE = BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_SESSION_RESTORE;
+  static const EventType NAVIGATION = BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_NAVIGATION;
+  static const EventType STARTUP = BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_STARTUP;
+  static const EventType REACHED_CODE = BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_REACHED_CODE;
+  static const EventType CONTENT_TRIGGER = BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_CONTENT_TRIGGER;
+  static const EventType TEST_RULE = BackgroundTracingMetadata_TriggerRule_NamedRule_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EventType kEventType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ContentTriggerNameHash kContentTriggerNameHash() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_HistogramNameHash =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      BackgroundTracingMetadata_TriggerRule_HistogramRule>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HistogramNameHash kHistogramNameHash() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HistogramMinTrigger kHistogramMinTrigger() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HistogramMaxTrigger kHistogramMaxTrigger() { return {}; }
+  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=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ 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(); }
+};
+
+class ChromeMetadataPacket : public ::protozero::Message {
+ public:
+  using Decoder = ChromeMetadataPacket_Decoder;
+  enum : int32_t {
+    kBackgroundTracingMetadataFieldNumber = 1,
+    kChromeVersionCodeFieldNumber = 2,
+    kEnabledCategoriesFieldNumber = 3,
+  };
+
+  using FieldMetadata_BackgroundTracingMetadata =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BackgroundTracingMetadata,
+      ChromeMetadataPacket>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BackgroundTracingMetadata kBackgroundTracingMetadata() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeVersionCode kChromeVersionCode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EnabledCategories kEnabledCategories() { return {}; }
+  void set_enabled_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EnabledCategories::kFieldId, data, 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);
+  }
+};
+
+} // 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;
+enum ChromeLegacyJsonTrace_TraceType : int32_t;
+enum ChromeTracedValue_NestedType : int32_t;
+
+enum ChromeLegacyJsonTrace_TraceType : int32_t {
+  ChromeLegacyJsonTrace_TraceType_USER_TRACE = 0,
+  ChromeLegacyJsonTrace_TraceType_SYSTEM_TRACE = 1,
+};
+
+const ChromeLegacyJsonTrace_TraceType ChromeLegacyJsonTrace_TraceType_MIN = ChromeLegacyJsonTrace_TraceType_USER_TRACE;
+const ChromeLegacyJsonTrace_TraceType ChromeLegacyJsonTrace_TraceType_MAX = ChromeLegacyJsonTrace_TraceType_SYSTEM_TRACE;
+
+enum ChromeTracedValue_NestedType : int32_t {
+  ChromeTracedValue_NestedType_DICT = 0,
+  ChromeTracedValue_NestedType_ARRAY = 1,
+};
+
+const ChromeTracedValue_NestedType ChromeTracedValue_NestedType_MIN = ChromeTracedValue_NestedType_DICT;
+const ChromeTracedValue_NestedType ChromeTracedValue_NestedType_MAX = ChromeTracedValue_NestedType_ARRAY;
+
+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,
+  };
+
+  using FieldMetadata_TraceEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeTraceEvent,
+      ChromeEventBundle>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceEvents kTraceEvents() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Metadata kMetadata() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LegacyFtraceOutput kLegacyFtraceOutput() { return {}; }
+  void add_legacy_ftrace_output(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LegacyFtraceOutput::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LegacyJsonTrace kLegacyJsonTrace() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StringTable kStringTable() { return {}; }
+  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,
+  };
+  using TraceType = ::perfetto::protos::pbzero::ChromeLegacyJsonTrace_TraceType;
+  static const TraceType USER_TRACE = ChromeLegacyJsonTrace_TraceType_USER_TRACE;
+  static const TraceType SYSTEM_TRACE = ChromeLegacyJsonTrace_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Data kData() { return {}; }
+  void set_data(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Data::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeMetadata>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StringValue kStringValue() { return {}; }
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BoolValue kBoolValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IntValue kIntValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_JsonValue kJsonValue() { return {}; }
+  void set_json_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_JsonValue::kFieldId, data, 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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Timestamp kTimestamp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Phase kPhase() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadId kThreadId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Duration kDuration() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadDuration kThreadDuration() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Scope kScope() { return {}; }
+  void set_scope(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Scope::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Id kId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CategoryGroupName kCategoryGroupName() { return {}; }
+  void set_category_group_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_CategoryGroupName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessId kProcessId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadTimestamp kThreadTimestamp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BindId kBindId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Args kArgs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NameIndex kNameIndex() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CategoryGroupNameIndex kCategoryGroupNameIndex() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeTraceEvent_Arg>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BoolValue kBoolValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UintValue kUintValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IntValue kIntValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DoubleValue kDoubleValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StringValue kStringValue() { return {}; }
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PointerValue kPointerValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_JsonValue kJsonValue() { return {}; }
+  void set_json_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_JsonValue::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TracedValue kTracedValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NameIndex kNameIndex() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeStringTableEntry>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Value kValue() { return {}; }
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Index kIndex() { return {}; }
+  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,
+  };
+  using NestedType = ::perfetto::protos::pbzero::ChromeTracedValue_NestedType;
+  static const NestedType DICT = ChromeTracedValue_NestedType_DICT;
+  static const NestedType ARRAY = ChromeTracedValue_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NestedType kNestedType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DictKeys kDictKeys() { return {}; }
+  void add_dict_keys(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DictKeys::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DictValues kDictValues() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ArrayValues kArrayValues() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IntValue kIntValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DoubleValue kDoubleValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BoolValue kBoolValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StringValue kStringValue() { return {}; }
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, 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/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;
+enum InodeFileMap_Entry_Type : int32_t;
+
+enum InodeFileMap_Entry_Type : int32_t {
+  InodeFileMap_Entry_Type_UNKNOWN = 0,
+  InodeFileMap_Entry_Type_FILE = 1,
+  InodeFileMap_Entry_Type_DIRECTORY = 2,
+};
+
+const InodeFileMap_Entry_Type InodeFileMap_Entry_Type_MIN = InodeFileMap_Entry_Type_UNKNOWN;
+const InodeFileMap_Entry_Type InodeFileMap_Entry_Type_MAX = InodeFileMap_Entry_Type_DIRECTORY;
+
+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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockDeviceId kBlockDeviceId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MountPoints kMountPoints() { return {}; }
+  void add_mount_points(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_MountPoints::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Entries kEntries() { return {}; }
+  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,
+  };
+  using Type = ::perfetto::protos::pbzero::InodeFileMap_Entry_Type;
+  static const Type UNKNOWN = InodeFileMap_Entry_Type_UNKNOWN;
+  static const Type FILE = InodeFileMap_Entry_Type_FILE;
+  static const Type DIRECTORY = InodeFileMap_Entry_Type_DIRECTORY;
+
+  using FieldMetadata_InodeNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InodeFileMap_Entry>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InodeNumber kInodeNumber() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Paths kPaths() { return {}; }
+  void add_paths(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Paths::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  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 BinderLockFtraceEvent;
+class BinderLockedFtraceEvent;
+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 CpuFrequencyFtraceEvent;
+class CpuFrequencyLimitsFtraceEvent;
+class CpuIdleFtraceEvent;
+class CpuhpEnterFtraceEvent;
+class CpuhpExitFtraceEvent;
+class CpuhpLatencyFtraceEvent;
+class CpuhpMultiEnterFtraceEvent;
+class CpuhpPauseFtraceEvent;
+class DmaAllocContiguousRetryFtraceEvent;
+class DmaHeapStatFtraceEvent;
+class DpuTracingMarkWriteFtraceEvent;
+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 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 G2dTracingMarkWriteFtraceEvent;
+class GenericFtraceEvent;
+class GpuFrequencyFtraceEvent;
+class GpuMemTotalFtraceEvent;
+class I2cReadFtraceEvent;
+class I2cReplyFtraceEvent;
+class I2cResultFtraceEvent;
+class I2cWriteFtraceEvent;
+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 KmallocFtraceEvent;
+class KmallocNodeFtraceEvent;
+class KmemCacheAllocFtraceEvent;
+class KmemCacheAllocNodeFtraceEvent;
+class KmemCacheFreeFtraceEvent;
+class LowmemoryKillFtraceEvent;
+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 MmVmscanDirectReclaimBeginFtraceEvent;
+class MmVmscanDirectReclaimEndFtraceEvent;
+class MmVmscanKswapdSleepFtraceEvent;
+class MmVmscanKswapdWakeFtraceEvent;
+class OomScoreAdjUpdateFtraceEvent;
+class PrintFtraceEvent;
+class RegulatorDisableCompleteFtraceEvent;
+class RegulatorDisableFtraceEvent;
+class RegulatorEnableCompleteFtraceEvent;
+class RegulatorEnableDelayFtraceEvent;
+class RegulatorEnableFtraceEvent;
+class RegulatorSetVoltageCompleteFtraceEvent;
+class RegulatorSetVoltageFtraceEvent;
+class RotatorBwAoAsContextFtraceEvent;
+class RssStatFtraceEvent;
+class SchedBlockedReasonFtraceEvent;
+class SchedCpuHotplugFtraceEvent;
+class SchedPiSetprioFtraceEvent;
+class SchedProcessExecFtraceEvent;
+class SchedProcessExitFtraceEvent;
+class SchedProcessForkFtraceEvent;
+class SchedProcessFreeFtraceEvent;
+class SchedProcessHangFtraceEvent;
+class SchedProcessWaitFtraceEvent;
+class SchedSwitchFtraceEvent;
+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 SyncPtFtraceEvent;
+class SyncTimelineFtraceEvent;
+class SyncWaitFtraceEvent;
+class SysEnterFtraceEvent;
+class SysExitFtraceEvent;
+class TaskNewtaskFtraceEvent;
+class TaskRenameFtraceEvent;
+class ThermalTemperatureFtraceEvent;
+class TracingMarkWriteFtraceEvent;
+class WorkqueueActivateWorkFtraceEvent;
+class WorkqueueExecuteEndFtraceEvent;
+class WorkqueueExecuteStartFtraceEvent;
+class WorkqueueQueueWorkFtraceEvent;
+class ZeroFtraceEvent;
+
+class FtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/358, /*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_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(); }
+};
+
+class FtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FtraceEvent_Decoder;
+  enum : int32_t {
+    kTimestampFieldNumber = 1,
+    kPidFieldNumber = 2,
+    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,
+  };
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Timestamp kTimestamp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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_Print =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PrintFtraceEvent,
+      FtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Print kPrint() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SchedSwitch kSchedSwitch() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuFrequency kCpuFrequency() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuFrequencyLimits kCpuFrequencyLimits() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuIdle kCpuIdle() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClockEnable kClockEnable() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClockDisable kClockDisable() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClockSetRate kClockSetRate() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SchedWakeup kSchedWakeup() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SchedBlockedReason kSchedBlockedReason() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SchedCpuHotplug kSchedCpuHotplug() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SchedWaking kSchedWaking() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IpiEntry kIpiEntry() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IpiExit kIpiExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IpiRaise kIpiRaise() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SoftirqEntry kSoftirqEntry() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SoftirqExit kSoftirqExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SoftirqRaise kSoftirqRaise() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_I2cRead kI2cRead() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_I2cWrite kI2cWrite() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_I2cResult kI2cResult() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_I2cReply kI2cReply() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SmbusRead kSmbusRead() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SmbusWrite kSmbusWrite() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SmbusResult kSmbusResult() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SmbusReply kSmbusReply() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LowmemoryKill kLowmemoryKill() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IrqHandlerEntry kIrqHandlerEntry() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IrqHandlerExit kIrqHandlerExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SyncPt kSyncPt() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SyncTimeline kSyncTimeline() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SyncWait kSyncWait() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4DaWriteBegin kExt4DaWriteBegin() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4DaWriteEnd kExt4DaWriteEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4SyncFileEnter kExt4SyncFileEnter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4SyncFileExit kExt4SyncFileExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockRqIssue kBlockRqIssue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmVmscanDirectReclaimBegin kMmVmscanDirectReclaimBegin() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmVmscanDirectReclaimEnd kMmVmscanDirectReclaimEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmVmscanKswapdWake kMmVmscanKswapdWake() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmVmscanKswapdSleep kMmVmscanKswapdSleep() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BinderTransaction kBinderTransaction() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BinderTransactionReceived kBinderTransactionReceived() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BinderSetPriority kBinderSetPriority() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BinderLock kBinderLock() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BinderLocked kBinderLocked() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BinderUnlock kBinderUnlock() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WorkqueueActivateWork kWorkqueueActivateWork() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WorkqueueExecuteEnd kWorkqueueExecuteEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WorkqueueExecuteStart kWorkqueueExecuteStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WorkqueueQueueWork kWorkqueueQueueWork() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RegulatorDisable kRegulatorDisable() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RegulatorDisableComplete kRegulatorDisableComplete() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RegulatorEnable kRegulatorEnable() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RegulatorEnableComplete kRegulatorEnableComplete() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RegulatorEnableDelay kRegulatorEnableDelay() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RegulatorSetVoltage kRegulatorSetVoltage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RegulatorSetVoltageComplete kRegulatorSetVoltageComplete() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CgroupAttachTask kCgroupAttachTask() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CgroupMkdir kCgroupMkdir() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CgroupRemount kCgroupRemount() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CgroupRmdir kCgroupRmdir() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CgroupTransferTasks kCgroupTransferTasks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CgroupDestroyRoot kCgroupDestroyRoot() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CgroupRelease kCgroupRelease() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CgroupRename kCgroupRename() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CgroupSetupRoot kCgroupSetupRoot() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdpCmdKickoff kMdpCmdKickoff() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdpCommit kMdpCommit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdpPerfSetOt kMdpPerfSetOt() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdpSsppChange kMdpSsppChange() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TracingMarkWrite kTracingMarkWrite() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdpCmdPingpongDone kMdpCmdPingpongDone() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdpCompareBw kMdpCompareBw() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdpPerfSetPanicLuts kMdpPerfSetPanicLuts() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdpSsppSet kMdpSsppSet() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdpCmdReadptrDone kMdpCmdReadptrDone() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdpMisrCrc kMdpMisrCrc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdpPerfSetQosLuts kMdpPerfSetQosLuts() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdpTraceCounter kMdpTraceCounter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdpCmdReleaseBw kMdpCmdReleaseBw() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdpMixerUpdate kMdpMixerUpdate() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdpPerfSetWmLevels kMdpPerfSetWmLevels() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdpVideoUnderrunDone kMdpVideoUnderrunDone() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdpCmdWaitPingpong kMdpCmdWaitPingpong() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdpPerfPrefillCalc kMdpPerfPrefillCalc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdpPerfUpdateBus kMdpPerfUpdateBus() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RotatorBwAoAsContext kRotatorBwAoAsContext() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmFilemapAddToPageCache kMmFilemapAddToPageCache() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmFilemapDeleteFromPageCache kMmFilemapDeleteFromPageCache() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmCompactionBegin kMmCompactionBegin() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmCompactionDeferCompaction kMmCompactionDeferCompaction() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmCompactionDeferred kMmCompactionDeferred() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmCompactionDeferReset kMmCompactionDeferReset() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmCompactionEnd kMmCompactionEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmCompactionFinished kMmCompactionFinished() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmCompactionIsolateFreepages kMmCompactionIsolateFreepages() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmCompactionIsolateMigratepages kMmCompactionIsolateMigratepages() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmCompactionKcompactdSleep kMmCompactionKcompactdSleep() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmCompactionKcompactdWake kMmCompactionKcompactdWake() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmCompactionMigratepages kMmCompactionMigratepages() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmCompactionSuitable kMmCompactionSuitable() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmCompactionTryToCompactPages kMmCompactionTryToCompactPages() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmCompactionWakeupKcompactd kMmCompactionWakeupKcompactd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SuspendResume kSuspendResume() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SchedWakeupNew kSchedWakeupNew() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockBioBackmerge kBlockBioBackmerge() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockBioBounce kBlockBioBounce() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockBioComplete kBlockBioComplete() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockBioFrontmerge kBlockBioFrontmerge() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockBioQueue kBlockBioQueue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockBioRemap kBlockBioRemap() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockDirtyBuffer kBlockDirtyBuffer() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockGetrq kBlockGetrq() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockPlug kBlockPlug() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockRqAbort kBlockRqAbort() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockRqComplete kBlockRqComplete() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockRqInsert kBlockRqInsert() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockRqRemap kBlockRqRemap() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockRqRequeue kBlockRqRequeue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockSleeprq kBlockSleeprq() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockSplit kBlockSplit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockTouchBuffer kBlockTouchBuffer() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockUnplug kBlockUnplug() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4AllocDaBlocks kExt4AllocDaBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4AllocateBlocks kExt4AllocateBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4AllocateInode kExt4AllocateInode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4BeginOrderedTruncate kExt4BeginOrderedTruncate() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4CollapseRange kExt4CollapseRange() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4DaReleaseSpace kExt4DaReleaseSpace() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4DaReserveSpace kExt4DaReserveSpace() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4DaUpdateReserveSpace kExt4DaUpdateReserveSpace() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4DaWritePages kExt4DaWritePages() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4DaWritePagesExtent kExt4DaWritePagesExtent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4DirectIOEnter kExt4DirectIOEnter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4DirectIOExit kExt4DirectIOExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4DiscardBlocks kExt4DiscardBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4DiscardPreallocations kExt4DiscardPreallocations() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4DropInode kExt4DropInode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4EsCacheExtent kExt4EsCacheExtent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4EsFindDelayedExtentRangeEnter kExt4EsFindDelayedExtentRangeEnter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4EsFindDelayedExtentRangeExit kExt4EsFindDelayedExtentRangeExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4EsInsertExtent kExt4EsInsertExtent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4EsLookupExtentEnter kExt4EsLookupExtentEnter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4EsLookupExtentExit kExt4EsLookupExtentExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4EsRemoveExtent kExt4EsRemoveExtent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4EsShrink kExt4EsShrink() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4EsShrinkCount kExt4EsShrinkCount() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4EsShrinkScanEnter kExt4EsShrinkScanEnter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4EsShrinkScanExit kExt4EsShrinkScanExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4EvictInode kExt4EvictInode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4ExtConvertToInitializedEnter kExt4ExtConvertToInitializedEnter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4ExtConvertToInitializedFastpath kExt4ExtConvertToInitializedFastpath() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4ExtHandleUnwrittenExtents kExt4ExtHandleUnwrittenExtents() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4ExtInCache kExt4ExtInCache() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4ExtLoadExtent kExt4ExtLoadExtent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4ExtMapBlocksEnter kExt4ExtMapBlocksEnter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4ExtMapBlocksExit kExt4ExtMapBlocksExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4ExtPutInCache kExt4ExtPutInCache() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4ExtRemoveSpace kExt4ExtRemoveSpace() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4ExtRemoveSpaceDone kExt4ExtRemoveSpaceDone() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4ExtRmIdx kExt4ExtRmIdx() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4ExtRmLeaf kExt4ExtRmLeaf() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4ExtShowExtent kExt4ExtShowExtent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4FallocateEnter kExt4FallocateEnter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4FallocateExit kExt4FallocateExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4FindDelallocRange kExt4FindDelallocRange() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4Forget kExt4Forget() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4FreeBlocks kExt4FreeBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4FreeInode kExt4FreeInode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4GetImpliedClusterAllocExit kExt4GetImpliedClusterAllocExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4GetReservedClusterAlloc kExt4GetReservedClusterAlloc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4IndMapBlocksEnter kExt4IndMapBlocksEnter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4IndMapBlocksExit kExt4IndMapBlocksExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4InsertRange kExt4InsertRange() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4Invalidatepage kExt4Invalidatepage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4JournalStart kExt4JournalStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4JournalStartReserved kExt4JournalStartReserved() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4JournalledInvalidatepage kExt4JournalledInvalidatepage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4JournalledWriteEnd kExt4JournalledWriteEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4LoadInode kExt4LoadInode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4LoadInodeBitmap kExt4LoadInodeBitmap() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4MarkInodeDirty kExt4MarkInodeDirty() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4MbBitmapLoad kExt4MbBitmapLoad() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4MbBuddyBitmapLoad kExt4MbBuddyBitmapLoad() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4MbDiscardPreallocations kExt4MbDiscardPreallocations() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4MbNewGroupPa kExt4MbNewGroupPa() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4MbNewInodePa kExt4MbNewInodePa() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4MbReleaseGroupPa kExt4MbReleaseGroupPa() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4MbReleaseInodePa kExt4MbReleaseInodePa() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4MballocAlloc kExt4MballocAlloc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4MballocDiscard kExt4MballocDiscard() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4MballocFree kExt4MballocFree() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4MballocPrealloc kExt4MballocPrealloc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4OtherInodeUpdateTime kExt4OtherInodeUpdateTime() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4PunchHole kExt4PunchHole() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4ReadBlockBitmapLoad kExt4ReadBlockBitmapLoad() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4Readpage kExt4Readpage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4Releasepage kExt4Releasepage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4RemoveBlocks kExt4RemoveBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4RequestBlocks kExt4RequestBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4RequestInode kExt4RequestInode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4SyncFs kExt4SyncFs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4TrimAllFree kExt4TrimAllFree() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4TrimExtent kExt4TrimExtent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4TruncateEnter kExt4TruncateEnter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4TruncateExit kExt4TruncateExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4UnlinkEnter kExt4UnlinkEnter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4UnlinkExit kExt4UnlinkExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4WriteBegin kExt4WriteBegin() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4WriteEnd kExt4WriteEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4Writepage kExt4Writepage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4Writepages kExt4Writepages() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4WritepagesResult kExt4WritepagesResult() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ext4ZeroRange kExt4ZeroRange() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TaskNewtask kTaskNewtask() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TaskRename kTaskRename() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SchedProcessExec kSchedProcessExec() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SchedProcessExit kSchedProcessExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SchedProcessFork kSchedProcessFork() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SchedProcessFree kSchedProcessFree() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SchedProcessHang kSchedProcessHang() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SchedProcessWait kSchedProcessWait() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsDoSubmitBio kF2fsDoSubmitBio() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsEvictInode kF2fsEvictInode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsFallocate kF2fsFallocate() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsGetDataBlock kF2fsGetDataBlock() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsGetVictim kF2fsGetVictim() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsIget kF2fsIget() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsIgetExit kF2fsIgetExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsNewInode kF2fsNewInode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsReadpage kF2fsReadpage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsReserveNewBlock kF2fsReserveNewBlock() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsSetPageDirty kF2fsSetPageDirty() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsSubmitWritePage kF2fsSubmitWritePage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsSyncFileEnter kF2fsSyncFileEnter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsSyncFileExit kF2fsSyncFileExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsSyncFs kF2fsSyncFs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsTruncate kF2fsTruncate() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsTruncateBlocksEnter kF2fsTruncateBlocksEnter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsTruncateBlocksExit kF2fsTruncateBlocksExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsTruncateDataBlocksRange kF2fsTruncateDataBlocksRange() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsTruncateInodeBlocksEnter kF2fsTruncateInodeBlocksEnter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsTruncateInodeBlocksExit kF2fsTruncateInodeBlocksExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsTruncateNode kF2fsTruncateNode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsTruncateNodesEnter kF2fsTruncateNodesEnter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsTruncateNodesExit kF2fsTruncateNodesExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsTruncatePartialNodes kF2fsTruncatePartialNodes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsUnlinkEnter kF2fsUnlinkEnter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsUnlinkExit kF2fsUnlinkExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsVmPageMkwrite kF2fsVmPageMkwrite() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsWriteBegin kF2fsWriteBegin() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsWriteCheckpoint kF2fsWriteCheckpoint() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_F2fsWriteEnd kF2fsWriteEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllocPagesIommuEnd kAllocPagesIommuEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllocPagesIommuFail kAllocPagesIommuFail() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllocPagesIommuStart kAllocPagesIommuStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllocPagesSysEnd kAllocPagesSysEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllocPagesSysFail kAllocPagesSysFail() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllocPagesSysStart kAllocPagesSysStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DmaAllocContiguousRetry kDmaAllocContiguousRetry() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IommuMapRange kIommuMapRange() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IommuSecPtblMapRangeEnd kIommuSecPtblMapRangeEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IommuSecPtblMapRangeStart kIommuSecPtblMapRangeStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IonAllocBufferEnd kIonAllocBufferEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IonAllocBufferFail kIonAllocBufferFail() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IonAllocBufferFallback kIonAllocBufferFallback() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IonAllocBufferStart kIonAllocBufferStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IonCpAllocRetry kIonCpAllocRetry() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IonCpSecureBufferEnd kIonCpSecureBufferEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IonCpSecureBufferStart kIonCpSecureBufferStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IonPrefetching kIonPrefetching() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IonSecureCmaAddToPoolEnd kIonSecureCmaAddToPoolEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IonSecureCmaAddToPoolStart kIonSecureCmaAddToPoolStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IonSecureCmaAllocateEnd kIonSecureCmaAllocateEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IonSecureCmaAllocateStart kIonSecureCmaAllocateStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IonSecureCmaShrinkPoolEnd kIonSecureCmaShrinkPoolEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IonSecureCmaShrinkPoolStart kIonSecureCmaShrinkPoolStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Kfree kKfree() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Kmalloc kKmalloc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_KmallocNode kKmallocNode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_KmemCacheAlloc kKmemCacheAlloc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_KmemCacheAllocNode kKmemCacheAllocNode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_KmemCacheFree kKmemCacheFree() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MigratePagesEnd kMigratePagesEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MigratePagesStart kMigratePagesStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MigrateRetry kMigrateRetry() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmPageAlloc kMmPageAlloc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmPageAllocExtfrag kMmPageAllocExtfrag() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmPageAllocZoneLocked kMmPageAllocZoneLocked() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmPageFree kMmPageFree() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmPageFreeBatched kMmPageFreeBatched() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmPagePcpuDrain kMmPagePcpuDrain() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RssStat kRssStat() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IonHeapShrink kIonHeapShrink() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IonHeapGrow kIonHeapGrow() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FenceInit kFenceInit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FenceDestroy kFenceDestroy() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FenceEnableSignal kFenceEnableSignal() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FenceSignaled kFenceSignaled() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClkEnable kClkEnable() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClkDisable kClkDisable() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClkSetRate kClkSetRate() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BinderTransactionAllocBuf kBinderTransactionAllocBuf() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SignalDeliver kSignalDeliver() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SignalGenerate kSignalGenerate() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OomScoreAdjUpdate kOomScoreAdjUpdate() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Generic kGeneric() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmEventRecord kMmEventRecord() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SysEnter kSysEnter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SysExit kSysExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Zero kZero() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuFrequency kGpuFrequency() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SdeTracingMarkWrite kSdeTracingMarkWrite() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MarkVictim kMarkVictim() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IonStat kIonStat() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IonBufferCreate kIonBufferCreate() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IonBufferDestroy kIonBufferDestroy() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ScmCallStart kScmCallStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ScmCallEnd kScmCallEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuMemTotal kGpuMemTotal() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThermalTemperature kThermalTemperature() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CdevUpdate kCdevUpdate() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuhpExit kCpuhpExit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuhpMultiEnter kCpuhpMultiEnter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuhpEnter kCpuhpEnter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuhpLatency kCpuhpLatency() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FastrpcDmaStat kFastrpcDmaStat() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DpuTracingMarkWrite kDpuTracingMarkWrite() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_G2dTracingMarkWrite kG2dTracingMarkWrite() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MaliTracingMarkWrite kMaliTracingMarkWrite() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DmaHeapStat kDmaHeapStat() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuhpPause kCpuhpPause() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SchedPiSetprio kSchedPiSetprio() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SdeSdeEvtlog kSdeSdeEvtlog() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SdeSdePerfCalcCrtc kSdeSdePerfCalcCrtc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SdeSdePerfCrtcUpdate kSdeSdePerfCrtcUpdate() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SdeSdePerfSetQosLuts kSdeSdePerfSetQosLuts() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SdeSdePerfUpdateBus kSdeSdePerfUpdateBus() { return {}; }
+  template <typename T = SdeSdePerfUpdateBusFtraceEvent> T* set_sde_sde_perf_update_bus() {
+    return BeginNestedMessage<T>(358);
+  }
+
+};
+
+} // 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,
+};
+
+const FtraceClock FtraceClock_MIN = FTRACE_CLOCK_UNSPECIFIED;
+const FtraceClock FtraceClock_MAX = FTRACE_CLOCK_LOCAL;
+
+class FtraceEventBundle_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*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(); }
+};
+
+class FtraceEventBundle : public ::protozero::Message {
+ public:
+  using Decoder = FtraceEventBundle_Decoder;
+  enum : int32_t {
+    kCpuFieldNumber = 1,
+    kEventFieldNumber = 2,
+    kLostEventsFieldNumber = 3,
+    kCompactSchedFieldNumber = 4,
+    kFtraceClockFieldNumber = 5,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cpu kCpu() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Event kEvent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LostEvents kLostEvents() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CompactSched kCompactSched() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FtraceClock kFtraceClock() { return {}; }
+  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);
+  }
+};
+
+class FtraceEventBundle_CompactSched_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*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); }
+};
+
+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,
+  };
+
+  using FieldMetadata_InternTable =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceEventBundle_CompactSched>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InternTable kInternTable() { return {}; }
+  void add_intern_table(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_InternTable::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SwitchTimestamp kSwitchTimestamp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SwitchPrevState kSwitchPrevState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SwitchNextPid kSwitchNextPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SwitchNextPrio kSwitchNextPrio() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SwitchNextCommIndex kSwitchNextCommIndex() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WakingTimestamp kWakingTimestamp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WakingPid kWakingPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WakingTargetCpu kWakingTargetCpu() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WakingPrio kWakingPrio() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WakingCommIndex kWakingCommIndex() { return {}; }
+  void set_waking_comm_index(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_WakingCommIndex::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;
+enum FtraceStats_Phase : int32_t;
+
+enum FtraceStats_Phase : int32_t {
+  FtraceStats_Phase_UNSPECIFIED = 0,
+  FtraceStats_Phase_START_OF_TRACE = 1,
+  FtraceStats_Phase_END_OF_TRACE = 2,
+};
+
+const FtraceStats_Phase FtraceStats_Phase_MIN = FtraceStats_Phase_UNSPECIFIED;
+const FtraceStats_Phase FtraceStats_Phase_MAX = FtraceStats_Phase_END_OF_TRACE;
+
+class FtraceStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*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(); }
+};
+
+class FtraceStats : public ::protozero::Message {
+ public:
+  using Decoder = FtraceStats_Decoder;
+  enum : int32_t {
+    kPhaseFieldNumber = 1,
+    kCpuStatsFieldNumber = 2,
+    kKernelSymbolsParsedFieldNumber = 3,
+    kKernelSymbolsMemKbFieldNumber = 4,
+  };
+  using Phase = ::perfetto::protos::pbzero::FtraceStats_Phase;
+  static const Phase UNSPECIFIED = FtraceStats_Phase_UNSPECIFIED;
+  static const Phase START_OF_TRACE = FtraceStats_Phase_START_OF_TRACE;
+  static const Phase END_OF_TRACE = FtraceStats_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Phase kPhase() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuStats kCpuStats() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_KernelSymbolsParsed kKernelSymbolsParsed() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_KernelSymbolsMemKb kKernelSymbolsMemKb() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceCpuStats>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cpu kCpu() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Entries kEntries() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Overrun kOverrun() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CommitOverrun kCommitOverrun() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BytesRead kBytesRead() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OldestEventTs kOldestEventTs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NowTs kNowTs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DroppedEvents kDroppedEvents() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReadEvents kReadEvents() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Before =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestBundleWrapper>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Before kBefore() { return {}; }
+  void set_before(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Before::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Bundle kBundle() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_After kAfter() { return {}; }
+  void set_after(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_After::kFieldId, data, 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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EventName kEventName() { return {}; }
+  void set_event_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EventName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Field kField() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GenericFtraceEvent_Field>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StrValue kStrValue() { return {}; }
+  void set_str_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StrValue::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IntValue kIntValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UintValue kUintValue() { return {}; }
+  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/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 BinderTransactionAllocBufFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*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(); }
+};
+
+class BinderTransactionAllocBufFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BinderTransactionAllocBufFtraceEvent_Decoder;
+  enum : int32_t {
+    kDataSizeFieldNumber = 1,
+    kDebugIdFieldNumber = 2,
+    kOffsetsSizeFieldNumber = 3,
+  };
+
+  using FieldMetadata_DataSize =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BinderTransactionAllocBufFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DataSize kDataSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DebugId kDebugId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OffsetsSize kOffsetsSize() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_Tag =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BinderUnlockFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tag kTag() { return {}; }
+  void set_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Tag =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BinderLockedFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tag kTag() { return {}; }
+  void set_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Tag =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BinderLockFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tag kTag() { return {}; }
+  void set_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Proc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderSetPriorityFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Proc kProc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Thread kThread() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OldPrio kOldPrio() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NewPrio kNewPrio() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DesiredPrio kDesiredPrio() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_DebugId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderTransactionReceivedFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DebugId kDebugId() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_DebugId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderTransactionFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DebugId kDebugId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TargetNode kTargetNode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ToProc kToProc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ToThread kToThread() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Reply kReply() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Code kCode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_NrRq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlockUnplugFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrRq kNrRq() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockTouchBufferFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sector kSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Size kSize() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockSplitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sector kSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NewSector kNewSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rwbs kRwbs() { return {}; }
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockSleeprqFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sector kSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrSector kNrSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rwbs kRwbs() { return {}; }
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqRequeueFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sector kSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrSector kNrSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Errors kErrors() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rwbs kRwbs() { return {}; }
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cmd kCmd() { return {}; }
+  void set_cmd(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqRemapFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sector kSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrSector kNrSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OldDev kOldDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OldSector kOldSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrBios kNrBios() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rwbs kRwbs() { return {}; }
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqInsertFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sector kSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrSector kNrSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Bytes kBytes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rwbs kRwbs() { return {}; }
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cmd kCmd() { return {}; }
+  void set_cmd(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, data, 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=*/6, /*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(); }
+};
+
+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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqCompleteFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sector kSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrSector kNrSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Errors kErrors() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rwbs kRwbs() { return {}; }
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cmd kCmd() { return {}; }
+  void set_cmd(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, data, 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 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqAbortFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sector kSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrSector kNrSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Errors kErrors() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rwbs kRwbs() { return {}; }
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cmd kCmd() { return {}; }
+  void set_cmd(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockPlugFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockGetrqFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sector kSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrSector kNrSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rwbs kRwbs() { return {}; }
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockDirtyBufferFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sector kSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Size kSize() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioRemapFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sector kSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrSector kNrSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OldDev kOldDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OldSector kOldSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rwbs kRwbs() { return {}; }
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioQueueFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sector kSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrSector kNrSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rwbs kRwbs() { return {}; }
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioFrontmergeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sector kSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrSector kNrSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rwbs kRwbs() { return {}; }
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioCompleteFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sector kSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrSector kNrSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Error kError() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rwbs kRwbs() { return {}; }
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioBounceFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sector kSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrSector kNrSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rwbs kRwbs() { return {}; }
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioBackmergeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sector kSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrSector kNrSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rwbs kRwbs() { return {}; }
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqIssueFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sector kSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrSector kNrSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Bytes kBytes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rwbs kRwbs() { return {}; }
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cmd kCmd() { return {}; }
+  void set_cmd(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupSetupRootFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Root kRoot() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SsMask kSsMask() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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=*/3, /*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(); }
+};
+
+class CgroupRenameFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupRenameFtraceEvent_Decoder;
+  enum : int32_t {
+    kRootFieldNumber = 1,
+    kIdFieldNumber = 2,
+    kCnameFieldNumber = 3,
+  };
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupRenameFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Root kRoot() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Id kId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cname kCname() { return {}; }
+  void set_cname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, data, 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);
+  }
+};
+
+class CgroupReleaseFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*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(); }
+};
+
+class CgroupReleaseFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupReleaseFtraceEvent_Decoder;
+  enum : int32_t {
+    kRootFieldNumber = 1,
+    kIdFieldNumber = 2,
+    kCnameFieldNumber = 3,
+  };
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupReleaseFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Root kRoot() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Id kId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cname kCname() { return {}; }
+  void set_cname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, data, 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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupDestroyRootFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Root kRoot() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SsMask kSsMask() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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=*/5, /*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(); }
+};
+
+class CgroupTransferTasksFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupTransferTasksFtraceEvent_Decoder;
+  enum : int32_t {
+    kDstRootFieldNumber = 1,
+    kDstIdFieldNumber = 2,
+    kPidFieldNumber = 3,
+    kCommFieldNumber = 4,
+    kCnameFieldNumber = 5,
+  };
+
+  using FieldMetadata_DstRoot =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupTransferTasksFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DstRoot kDstRoot() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DstId kDstId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cname kCname() { return {}; }
+  void set_cname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, data, 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);
+  }
+};
+
+class CgroupRmdirFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*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(); }
+};
+
+class CgroupRmdirFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupRmdirFtraceEvent_Decoder;
+  enum : int32_t {
+    kRootFieldNumber = 1,
+    kIdFieldNumber = 2,
+    kCnameFieldNumber = 3,
+  };
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupRmdirFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Root kRoot() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Id kId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cname kCname() { return {}; }
+  void set_cname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, data, 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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupRemountFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Root kRoot() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SsMask kSsMask() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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=*/3, /*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(); }
+};
+
+class CgroupMkdirFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupMkdirFtraceEvent_Decoder;
+  enum : int32_t {
+    kRootFieldNumber = 1,
+    kIdFieldNumber = 2,
+    kCnameFieldNumber = 3,
+  };
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupMkdirFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Root kRoot() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Id kId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cname kCname() { return {}; }
+  void set_cname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, data, 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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_DstRoot =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupAttachTaskFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DstRoot kDstRoot() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DstId kDstId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cname kCname() { return {}; }
+  void set_cname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DstLevel kDstLevel() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DstPath kDstPath() { return {}; }
+  void set_dst_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DstPath::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ClkSetRateFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rate kRate() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ClkDisableFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ClkEnableFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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=*/3, /*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(); }
+};
+
+class MmCompactionWakeupKcompactdFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionWakeupKcompactdFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+    kOrderFieldNumber = 2,
+    kClasszoneIdxFieldNumber = 3,
+  };
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionWakeupKcompactdFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nid kNid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClasszoneIdx kClasszoneIdx() { return {}; }
+  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);
+  }
+};
+
+class MmCompactionTryToCompactPagesFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*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(); }
+};
+
+class MmCompactionTryToCompactPagesFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionTryToCompactPagesFtraceEvent_Decoder;
+  enum : int32_t {
+    kOrderFieldNumber = 1,
+    kGfpMaskFieldNumber = 2,
+    kModeFieldNumber = 3,
+  };
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionTryToCompactPagesFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GfpMask kGfpMask() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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 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,
+  };
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionSuitableFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nid kNid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Idx kIdx() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_NrMigrated =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionMigratepagesFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrMigrated kNrMigrated() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrFailed kNrFailed() { return {}; }
+  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=*/3, /*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(); }
+};
+
+class MmCompactionKcompactdWakeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionKcompactdWakeFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+    kOrderFieldNumber = 2,
+    kClasszoneIdxFieldNumber = 3,
+  };
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionKcompactdWakeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nid kNid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClasszoneIdx kClasszoneIdx() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionKcompactdSleepFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nid kNid() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_StartPfn =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionIsolateMigratepagesFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StartPfn kStartPfn() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EndPfn kEndPfn() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrScanned kNrScanned() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrTaken kNrTaken() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_StartPfn =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionIsolateFreepagesFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StartPfn kStartPfn() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EndPfn kEndPfn() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrScanned kNrScanned() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrTaken kNrTaken() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionFinishedFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nid kNid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Idx kIdx() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_ZoneStart =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionEndFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ZoneStart kZoneStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MigratePfn kMigratePfn() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FreePfn kFreePfn() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ZoneEnd kZoneEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sync kSync() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Status kStatus() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferResetFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nid kNid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Idx kIdx() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Considered kConsidered() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DeferShift kDeferShift() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OrderFailed kOrderFailed() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferredFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nid kNid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Idx kIdx() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Considered kConsidered() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DeferShift kDeferShift() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OrderFailed kOrderFailed() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferCompactionFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nid kNid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Idx kIdx() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Considered kConsidered() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DeferShift kDeferShift() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OrderFailed kOrderFailed() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_ZoneStart =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionBeginFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ZoneStart kZoneStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MigratePfn kMigratePfn() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FreePfn kFreePfn() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ZoneEnd kZoneEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sync kSync() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_ActiveCpus =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpPauseFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ActiveCpus kActiveCpus() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cpus kCpus() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pause kPause() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Time kTime() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpLatencyFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cpu kCpu() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_State kState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Time kTime() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpEnterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cpu kCpu() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Fun kFun() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Idx kIdx() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Target kTarget() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpMultiEnterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cpu kCpu() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Fun kFun() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Idx kIdx() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Target kTarget() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cpu kCpu() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Idx kIdx() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_State kState() { return {}; }
+  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/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,
+  };
+
+  using FieldMetadata_Inode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DmaHeapStatFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Inode kInode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TotalAllocated kTotalAllocated() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DpuTracingMarkWriteFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceName kTraceName() { return {}; }
+  void set_trace_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceBegin kTraceBegin() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Value kValue() { return {}; }
+  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/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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ZeroRangeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Offset kOffset() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepagesResultFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PagesWritten kPagesWritten() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PagesSkipped kPagesSkipped() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WritebackIndex kWritebackIndex() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SyncMode kSyncMode() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepagesFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrToWrite kNrToWrite() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PagesSkipped kPagesSkipped() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RangeStart kRangeStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RangeEnd kRangeEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WritebackIndex kWritebackIndex() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SyncMode kSyncMode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ForKupdate kForKupdate() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RangeCyclic kRangeCyclic() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepageFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Index kIndex() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WriteEndFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pos kPos() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Copied kCopied() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WriteBeginFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pos kPos() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4UnlinkExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4UnlinkEnterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Parent kParent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Size kSize() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4TruncateExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Blocks kBlocks() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4TruncateEnterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Blocks kBlocks() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_DevMajor =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4TrimExtentFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DevMajor kDevMajor() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DevMinor kDevMinor() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Group kGroup() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Start kStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_DevMajor =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4TrimAllFreeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DevMajor kDevMajor() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DevMinor kDevMinor() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Group kGroup() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Start kStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4SyncFsFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Wait kWait() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RequestInodeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dir kDir() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Logical kLogical() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lleft kLleft() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lright kLright() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Goal kGoal() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pleft kPleft() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pright kPright() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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=*/8, /*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(); }
+};
+
+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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_From kFrom() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_To kTo() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Partial kPartial() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EePblk kEePblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EeLblk kEeLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EeLen kEeLen() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ReleasepageFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Index kIndex() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ReadpageFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Index kIndex() { return {}; }
+  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=*/2, /*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(); }
+};
+
+class Ext4ReadBlockBitmapLoadFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ReadBlockBitmapLoadFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kGroupFieldNumber = 2,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ReadBlockBitmapLoadFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Group kGroup() { return {}; }
+  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 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4PunchHoleFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Offset kOffset() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4OtherInodeUpdateTimeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OrigIno kOrigIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Uid kUid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Gid kGid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OrigLogical kOrigLogical() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OrigStart kOrigStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OrigGroup kOrigGroup() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OrigLen kOrigLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ResultLogical kResultLogical() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ResultStart kResultStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ResultGroup kResultGroup() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ResultLen kResultLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocFreeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ResultStart kResultStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ResultGroup kResultGroup() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ResultLen kResultLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocDiscardFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ResultStart kResultStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ResultGroup kResultGroup() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ResultLen kResultLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OrigLogical kOrigLogical() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OrigStart kOrigStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OrigGroup kOrigGroup() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OrigLen kOrigLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GoalLogical kGoalLogical() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GoalStart kGoalStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GoalGroup kGoalGroup() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GoalLen kGoalLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ResultLogical kResultLogical() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ResultStart kResultStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ResultGroup kResultGroup() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ResultLen kResultLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Found kFound() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Groups kGroups() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Buddy kBuddy() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tail kTail() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cr kCr() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbReleaseInodePaFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Block kBlock() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Count kCount() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbReleaseGroupPaFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PaPstart kPaPstart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PaLen kPaLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbNewInodePaFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PaPstart kPaPstart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PaLstart kPaLstart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PaLen kPaLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbNewGroupPaFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PaPstart kPaPstart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PaLstart kPaLstart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PaLen kPaLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbDiscardPreallocationsFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Needed kNeeded() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbBuddyBitmapLoadFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Group kGroup() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbBitmapLoadFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Group kGroup() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MarkInodeDirtyFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ip kIp() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4LoadInodeBitmapFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Group kGroup() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4LoadInodeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalledWriteEndFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pos kPos() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Copied kCopied() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalledInvalidatepageFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Index kIndex() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Offset kOffset() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Length kLength() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalStartReservedFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ip kIp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Blocks kBlocks() { return {}; }
+  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=*/5, /*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(); }
+};
+
+class Ext4JournalStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4JournalStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kIpFieldNumber = 2,
+    kBlocksFieldNumber = 3,
+    kRsvBlocksFieldNumber = 4,
+    kNblocksFieldNumber = 5,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalStartFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ip kIp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Blocks kBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RsvBlocks kRsvBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nblocks kNblocks() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4InvalidatepageFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Index kIndex() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Offset kOffset() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Length kLength() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4InsertRangeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Offset kOffset() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4IndMapBlocksExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pblk kPblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lblk kLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mflags kMflags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4IndMapBlocksEnterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lblk kLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4GetReservedClusterAllocFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lblk kLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4GetImpliedClusterAllocExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lblk kLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pblk kPblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FreeInodeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Uid kUid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Gid kGid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Blocks kBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FreeBlocksFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Block kBlock() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Count kCount() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ForgetFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Block kBlock() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IsMetadata kIsMetadata() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FindDelallocRangeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_From kFrom() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_To kTo() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Reverse kReverse() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Found kFound() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FoundBlk kFoundBlk() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FallocateExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pos kPos() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Blocks kBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FallocateEnterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Offset kOffset() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pos kPos() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtShowExtentFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pblk kPblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lblk kLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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=*/7, /*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(); }
+};
+
+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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Partial kPartial() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Start kStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EeLblk kEeLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EePblk kEePblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EeLen kEeLen() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRmIdxFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pblk kPblk() { return {}; }
+  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=*/7, /*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(); }
+};
+
+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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Start kStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_End kEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Depth kDepth() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Partial kPartial() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EhEntries kEhEntries() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRemoveSpaceFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Start kStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_End kEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Depth kDepth() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtPutInCacheFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lblk kLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Start kStart() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtMapBlocksExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pblk kPblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lblk kLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mflags kMflags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtMapBlocksEnterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lblk kLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtLoadExtentFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pblk kPblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lblk kLblk() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtInCacheFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lblk kLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtHandleUnwrittenExtentsFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lblk kLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pblk kPblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Allocated kAllocated() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Newblk kNewblk() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MLblk kMLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MLen kMLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ULblk kULblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ULen kULen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UPblk kUPblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ILblk kILblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ILen kILen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IPblk kIPblk() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtConvertToInitializedEnterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MLblk kMLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MLen kMLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ULblk kULblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ULen kULen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UPblk kUPblk() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EvictInodeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nlink kNlink() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsShrinkScanExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrShrunk kNrShrunk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CacheCnt kCacheCnt() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsShrinkScanEnterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrToScan kNrToScan() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CacheCnt kCacheCnt() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsShrinkCountFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrToScan kNrToScan() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CacheCnt kCacheCnt() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsShrinkFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrShrunk kNrShrunk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ScanTime kScanTime() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrSkipped kNrSkipped() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Retried kRetried() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsRemoveExtentFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lblk kLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsLookupExtentExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lblk kLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pblk kPblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Status kStatus() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Found kFound() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsLookupExtentEnterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lblk kLblk() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsInsertExtentFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lblk kLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pblk kPblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Status kStatus() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsFindDelayedExtentRangeExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lblk kLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pblk kPblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Status kStatus() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsFindDelayedExtentRangeEnterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lblk kLblk() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsCacheExtentFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lblk kLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pblk kPblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Status kStatus() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DropInodeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Drop kDrop() { return {}; }
+  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=*/2, /*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(); }
+};
+
+class Ext4DiscardPreallocationsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DiscardPreallocationsFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DiscardPreallocationsFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DiscardBlocksFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Blk kBlk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Count kCount() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DirectIOExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pos kPos() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rw kRw() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DirectIOEnterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pos kPos() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rw kRw() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWritePagesExtentFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lblk kLblk() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FirstPage kFirstPage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrToWrite kNrToWrite() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SyncMode kSyncMode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BBlocknr kBBlocknr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BSize kBSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BState kBState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IoDone kIoDone() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PagesWritten kPagesWritten() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaUpdateReserveSpaceFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IBlocks kIBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UsedBlocks kUsedBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReservedDataBlocks kReservedDataBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReservedMetaBlocks kReservedMetaBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllocatedMetaBlocks kAllocatedMetaBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_QuotaClaim kQuotaClaim() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaReserveSpaceFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IBlocks kIBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReservedDataBlocks kReservedDataBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReservedMetaBlocks kReservedMetaBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MdNeeded kMdNeeded() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaReleaseSpaceFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IBlocks kIBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FreedBlocks kFreedBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReservedDataBlocks kReservedDataBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReservedMetaBlocks kReservedMetaBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllocatedMetaBlocks kAllocatedMetaBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4CollapseRangeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Offset kOffset() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4BeginOrderedTruncateFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NewSize kNewSize() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateInodeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dir kDir() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Block kBlock() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Logical kLogical() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lleft kLleft() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lright kLright() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Goal kGoal() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pleft kPleft() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pright kPright() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocDaBlocksFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DataBlocks kDataBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MetaBlocks kMetaBlocks() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4SyncFileExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4SyncFileEnterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Parent kParent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Datasync kDatasync() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWriteEndFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pos kPos() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Copied kCopied() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWriteBeginFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pos kPos() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsWriteEndFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pos kPos() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Copied kCopied() { return {}; }
+  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=*/3, /*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(); }
+};
+
+class F2fsWriteCheckpointFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsWriteCheckpointFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kIsUmountFieldNumber = 2,
+    kMsgFieldNumber = 3,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsWriteCheckpointFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IsUmount kIsUmount() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Msg kMsg() { return {}; }
+  void set_msg(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Msg::kFieldId, data, 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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsWriteBeginFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pos kPos() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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=*/6, /*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(); }
+};
+
+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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsVmPageMkwriteFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dir kDir() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Index kIndex() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dirty kDirty() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsUnlinkExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsUnlinkEnterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Size kSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Blocks kBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncatePartialNodesFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nid kNid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Depth kDepth() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Err kErr() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateNodesExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateNodesEnterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nid kNid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlkAddr kBlkAddr() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateNodeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nid kNid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlkAddr kBlkAddr() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateInodeBlocksExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateInodeBlocksEnterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Size kSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Blocks kBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_From kFrom() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateDataBlocksRangeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nid kNid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ofs kOfs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Free kFree() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateBlocksExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateBlocksEnterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Size kSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Blocks kBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_From kFrom() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pino kPino() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Size kSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nlink kNlink() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Blocks kBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Advise kAdvise() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSyncFsFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dirty kDirty() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Wait kWait() { return {}; }
+  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=*/5, /*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(); }
+};
+
+class F2fsSyncFileExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsSyncFileExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kNeedCpFieldNumber = 3,
+    kDatasyncFieldNumber = 4,
+    kRetFieldNumber = 5,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSyncFileExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NeedCp kNeedCp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Datasync kDatasync() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSyncFileEnterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pino kPino() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Size kSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nlink kNlink() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Blocks kBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Advise kAdvise() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSubmitWritePageFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Index kIndex() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Block kBlock() { return {}; }
+  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=*/6, /*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(); }
+};
+
+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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSetPageDirtyFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dir kDir() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Index kIndex() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dirty kDirty() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsReserveNewBlockFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nid kNid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OfsInNode kOfsInNode() { return {}; }
+  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=*/5, /*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(); }
+};
+
+class F2fsReadpageFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsReadpageFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIndexFieldNumber = 3,
+    kBlkaddrFieldNumber = 4,
+    kTypeFieldNumber = 5,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsReadpageFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Index kIndex() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Blkaddr kBlkaddr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  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 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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsNewInodeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIgetExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIgetFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pino kPino() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Size kSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nlink kNlink() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Blocks kBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Advise kAdvise() { return {}; }
+  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=*/10, /*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(); }
+};
+
+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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsGetVictimFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GcType kGcType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllocMode kAllocMode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GcMode kGcMode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Victim kVictim() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OfsUnit kOfsUnit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PreVictim kPreVictim() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Prefree kPrefree() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Free kFree() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsGetDataBlockFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Iblock kIblock() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BhStart kBhStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BhSize kBhSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsFallocateFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Offset kOffset() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Size kSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Blocks kBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsEvictInodeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ino kIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pino kPino() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Size kSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nlink kNlink() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Blocks kBlocks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Advise kAdvise() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsDoSubmitBioFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dev kDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Btype kBtype() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sync kSync() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sector kSector() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Size kSize() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Cid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FastrpcDmaStatFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cid kCid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TotalAllocated kTotalAllocated() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceSignaledFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Context kContext() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Driver kDriver() { return {}; }
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Seqno kSeqno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Timeline kTimeline() { return {}; }
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceEnableSignalFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Context kContext() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Driver kDriver() { return {}; }
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Seqno kSeqno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Timeline kTimeline() { return {}; }
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceDestroyFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Context kContext() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Driver kDriver() { return {}; }
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Seqno kSeqno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Timeline kTimeline() { return {}; }
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceInitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Context kContext() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Driver kDriver() { return {}; }
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Seqno kSeqno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Timeline kTimeline() { return {}; }
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapDeleteFromPageCacheFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pfn kPfn() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IIno kIIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Index kIndex() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SDev kSDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Page kPage() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapAddToPageCacheFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pfn kPfn() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IIno kIIno() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Index kIndex() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SDev kSDev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Page kPage() { return {}; }
+  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 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,
+  };
+
+  using FieldMetadata_Ip =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PrintFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ip kIp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Buf kBuf() { return {}; }
+  void set_buf(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Buf::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      G2dTracingMarkWriteFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Value kValue() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_GpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuMemTotalFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuId kGpuId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Size kSize() { return {}; }
+  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/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,
+  };
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SmbusReplyFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AdapterNr kAdapterNr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Addr kAddr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Command kCommand() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Protocol kProtocol() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SmbusResultFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AdapterNr kAdapterNr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Addr kAddr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReadWrite kReadWrite() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Command kCommand() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Res kRes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Protocol kProtocol() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SmbusWriteFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AdapterNr kAdapterNr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Addr kAddr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Command kCommand() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Protocol kProtocol() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SmbusReadFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AdapterNr kAdapterNr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Addr kAddr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Command kCommand() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Protocol kProtocol() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      I2cReplyFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AdapterNr kAdapterNr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MsgNr kMsgNr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Addr kAddr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Buf kBuf() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      I2cResultFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AdapterNr kAdapterNr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrMsgs kNrMsgs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      I2cWriteFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AdapterNr kAdapterNr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MsgNr kMsgNr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Addr kAddr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Buf kBuf() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      I2cReadFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AdapterNr kAdapterNr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MsgNr kMsgNr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Addr kAddr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_BufferId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonStatFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BufferId kBufferId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TotalAllocated kTotalAllocated() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_TargetCpus =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IpiRaiseFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TargetCpus kTargetCpus() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Reason kReason() { return {}; }
+  void set_reason(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Reason::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Reason =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IpiExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Reason kReason() { return {}; }
+  void set_reason(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Reason::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Reason =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IpiEntryFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Reason kReason() { return {}; }
+  void set_reason(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Reason::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Irq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IrqHandlerExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Irq kIrq() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Irq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IrqHandlerEntryFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Irq kIrq() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Handler kHandler() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Vec =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SoftirqRaiseFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Vec kVec() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Vec =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SoftirqExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Vec kVec() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Vec =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SoftirqEntryFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Vec kVec() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonBufferDestroyFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Addr kAddr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonBufferCreateFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Addr kAddr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonHeapGrowFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HeapName kHeapName() { return {}; }
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TotalAllocated kTotalAllocated() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonHeapShrinkFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HeapName kHeapName() { return {}; }
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TotalAllocated kTotalAllocated() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Member =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      RssStatFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Member kMember() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Size kSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Curr kCurr() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MmId kMmId() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Migratetype =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPagePcpuDrainFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Migratetype kMigratetype() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Page kPage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pfn kPfn() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Cold =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPageFreeBatchedFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cold kCold() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Page kPage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pfn kPfn() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmPageFreeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Page kPage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pfn kPfn() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Migratetype =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPageAllocZoneLockedFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Migratetype kMigratetype() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Page kPage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pfn kPfn() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_AllocMigratetype =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPageAllocExtfragFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllocMigratetype kAllocMigratetype() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllocOrder kAllocOrder() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FallbackMigratetype kFallbackMigratetype() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FallbackOrder kFallbackOrder() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Page kPage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChangeOwnership kChangeOwnership() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pfn kPfn() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmPageAllocFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GfpFlags kGfpFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Migratetype kMigratetype() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Page kPage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pfn kPfn() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Tries =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MigrateRetryFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tries kTries() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MigratePagesStartFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MigratePagesEndFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_CallSite =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheFreeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CallSite kCallSite() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ptr kPtr() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_BytesAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheAllocNodeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BytesAlloc kBytesAlloc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BytesReq kBytesReq() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CallSite kCallSite() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GfpFlags kGfpFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Node kNode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ptr kPtr() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_BytesAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheAllocFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BytesAlloc kBytesAlloc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BytesReq kBytesReq() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CallSite kCallSite() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GfpFlags kGfpFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ptr kPtr() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_BytesAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmallocNodeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BytesAlloc kBytesAlloc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BytesReq kBytesReq() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CallSite kCallSite() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GfpFlags kGfpFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Node kNode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ptr kPtr() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_BytesAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmallocFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BytesAlloc kBytesAlloc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BytesReq kBytesReq() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CallSite kCallSite() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GfpFlags kGfpFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ptr kPtr() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_CallSite =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KfreeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CallSite kCallSite() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ptr kPtr() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_DrainedSize =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaShrinkPoolStartFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DrainedSize kDrainedSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SkippedSize kSkippedSize() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_DrainedSize =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaShrinkPoolEndFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DrainedSize kDrainedSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SkippedSize kSkippedSize() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Align =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaAllocateStartFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Align kAlign() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HeapName kHeapName() { return {}; }
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Align =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaAllocateEndFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Align kAlign() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HeapName kHeapName() { return {}; }
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_IsPrefetch =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonSecureCmaAddToPoolStartFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IsPrefetch kIsPrefetch() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PoolTotal kPoolTotal() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_IsPrefetch =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonSecureCmaAddToPoolEndFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IsPrefetch kIsPrefetch() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PoolTotal kPoolTotal() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonPrefetchingFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Align =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonCpSecureBufferStartFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Align kAlign() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HeapName kHeapName() { return {}; }
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Align =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonCpSecureBufferEndFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Align kAlign() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HeapName kHeapName() { return {}; }
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Tries =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IonCpAllocRetryFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tries kTries() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_ClientName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferStartFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClientName kClientName() { return {}; }
+  void set_client_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HeapName kHeapName() { return {}; }
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mask kMask() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_ClientName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferFallbackFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClientName kClientName() { return {}; }
+  void set_client_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Error kError() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HeapName kHeapName() { return {}; }
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mask kMask() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_ClientName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferFailFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClientName kClientName() { return {}; }
+  void set_client_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Error kError() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HeapName kHeapName() { return {}; }
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mask kMask() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_ClientName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferEndFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClientName kClientName() { return {}; }
+  void set_client_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HeapName kHeapName() { return {}; }
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mask kMask() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IommuSecPtblMapRangeStartFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Num kNum() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pa kPa() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SecId kSecId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Va kVa() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IommuSecPtblMapRangeEndFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Num kNum() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pa kPa() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SecId kSecId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Va kVa() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_ChunkSize =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IommuMapRangeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChunkSize kChunkSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Len kLen() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pa kPa() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Va kVa() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Tries =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DmaAllocContiguousRetryFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tries kTries() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesSysStartFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GfpFlags kGfpFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesSysFailFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GfpFlags kGfpFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesSysEndFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GfpFlags kGfpFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesIommuStartFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GfpFlags kGfpFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesIommuFailFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GfpFlags kGfpFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesIommuEndFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GfpFlags kGfpFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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/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,
+  };
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LowmemoryKillFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PagecacheSize kPagecacheSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PagecacheLimit kPagecacheLimit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Free kFree() { return {}; }
+  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/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 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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      MaliTracingMarkWriteFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Value kValue() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      RotatorBwAoAsContextFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_State kState() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Client =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MdpPerfUpdateBusFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Client kClient() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AbQuota kAbQuota() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IbQuota kIbQuota() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Pnum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pnum kPnum() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LatencyBuf kLatencyBuf() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ot kOt() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_YBuf kYBuf() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_YScaler kYScaler() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PpLines kPpLines() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PpBytes kPpBytes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PostSc kPostSc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FbcBytes kFbcBytes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PrefillBytes kPrefillBytes() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_CtlNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCmdWaitPingpongFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CtlNum kCtlNum() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_KickoffCnt kKickoffCnt() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_CtlNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpVideoUnderrunDoneFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CtlNum kCtlNum() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UnderrunCnt kUnderrunCnt() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Pnum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetWmLevelsFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pnum kPnum() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UseSpace kUseSpace() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PriorityBytes kPriorityBytes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Wm0 kWm0() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Wm1 kWm1() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Wm2 kWm2() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MbCnt kMbCnt() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MbSize kMbSize() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_MixerNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpMixerUpdateFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MixerNum kMixerNum() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_CtlNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCmdReleaseBwFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CtlNum kCtlNum() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MdpTraceCounterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CounterName kCounterName() { return {}; }
+  void set_counter_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_CounterName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Value kValue() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Pnum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetQosLutsFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pnum kPnum() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Fmt kFmt() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Intf kIntf() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rot kRot() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Fl kFl() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lut kLut() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Linear kLinear() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_BlockId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpMisrCrcFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BlockId kBlockId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VsyncCnt kVsyncCnt() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Crc kCrc() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_CtlNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCmdReadptrDoneFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CtlNum kCtlNum() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_KoffCnt kKoffCnt() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Num =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Num kNum() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PlayCnt kPlayCnt() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mixer kMixer() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Stage kStage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Format kFormat() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ImgW kImgW() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ImgH kImgH() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SrcX kSrcX() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SrcY kSrcY() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SrcW kSrcW() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SrcH kSrcH() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DstX kDstX() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DstY kDstY() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DstW kDstW() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DstH kDstH() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Pnum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetPanicLutsFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pnum kPnum() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Fmt kFmt() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mode kMode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PanicLut kPanicLut() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RobustLut kRobustLut() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_NewAb =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MdpCompareBwFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NewAb kNewAb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NewIb kNewIb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NewWb kNewWb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OldAb kOldAb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OldIb kOldIb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OldWb kOldWb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ParamsChanged kParamsChanged() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UpdateBw kUpdateBw() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_CtlNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCmdPingpongDoneFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CtlNum kCtlNum() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IntfNum kIntfNum() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PpNum kPpNum() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_KoffCnt kKoffCnt() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingMarkWriteFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceName kTraceName() { return {}; }
+  void set_trace_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceBegin kTraceBegin() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Num =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Num kNum() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PlayCnt kPlayCnt() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mixer kMixer() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Stage kStage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flags kFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Format kFormat() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ImgW kImgW() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ImgH kImgH() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SrcX kSrcX() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SrcY kSrcY() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SrcW kSrcW() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SrcH kSrcH() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DstX kDstX() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DstY kDstY() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DstW kDstW() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DstH kDstH() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Pnum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetOtFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pnum kPnum() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_XinId kXinId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RdLim kRdLim() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IsVbifRt kIsVbifRt() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Num =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCommitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Num kNum() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PlayCnt kPlayCnt() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClkRate kClkRate() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Bandwidth kBandwidth() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_CtlNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCmdKickoffFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CtlNum kCtlNum() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_KickoffCnt kKickoffCnt() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_AvgLat =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmEventRecordFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AvgLat kAvgLat() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Count kCount() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MaxLat kMaxLat() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  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/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,
+  };
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MarkVictimFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      OomScoreAdjUpdateFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OomScoreAdj kOomScoreAdj() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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/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 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,
+  };
+
+  using FieldMetadata_GpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuFrequencyFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuId kGpuId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_State kState() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Action =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SuspendResumeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Action kAction() { return {}; }
+  void set_action(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Action::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Val kVal() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Start kStart() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ClockSetRateFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_State kState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuId kCpuId() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ClockDisableFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_State kState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuId kCpuId() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ClockEnableFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_State kState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuId kCpuId() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuIdleFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_State kState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuId kCpuId() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_MinFreq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuFrequencyLimitsFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MinFreq kMinFreq() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MaxFreq kMaxFreq() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuId kCpuId() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuFrequencyFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_State kState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuId kCpuId() { return {}; }
+  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/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,
+  };
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      SysExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Id kId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ret kRet() { return {}; }
+  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=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ 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(); }
+};
+
+class SysEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SysEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+  };
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      SysEnterFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Id kId() { return {}; }
+  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);
+  }
+};
+
+} // 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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorSetVoltageCompleteFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Val kVal() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorSetVoltageFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Min kMin() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Max kMax() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorEnableDelayFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorEnableCompleteFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorEnableFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorDisableCompleteFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorDisableFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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/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 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,
+  };
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedPiSetprioFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Newprio kNewprio() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Oldprio kOldprio() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessWaitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Prio kPrio() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessHangFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessFreeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Prio kPrio() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_ParentComm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessForkFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ParentComm kParentComm() { return {}; }
+  void set_parent_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ParentComm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ParentPid kParentPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChildComm kChildComm() { return {}; }
+  void set_child_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ChildComm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChildPid kChildPid() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessExitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tgid kTgid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Prio kPrio() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Filename =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessExecFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Filename kFilename() { return {}; }
+  void set_filename(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Filename::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OldPid kOldPid() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedWakeupNewFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Prio kPrio() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Success kSuccess() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TargetCpu kTargetCpu() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedWakingFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Prio kPrio() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Success kSuccess() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TargetCpu kTargetCpu() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_AffectedCpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedCpuHotplugFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AffectedCpu kAffectedCpu() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Error kError() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Status kStatus() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedBlockedReasonFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Caller kCaller() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IoWait kIoWait() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedWakeupFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Prio kPrio() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Success kSuccess() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TargetCpu kTargetCpu() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_PrevComm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedSwitchFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PrevComm kPrevComm() { return {}; }
+  void set_prev_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_PrevComm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PrevPid kPrevPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PrevPrio kPrevPrio() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PrevState kPrevState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NextComm kNextComm() { return {}; }
+  void set_next_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_NextComm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NextPid kNextPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NextPrio kNextPrio() { return {}; }
+  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;
+};
+
+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,
+  };
+
+  using FieldMetadata_Arginfo =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ScmCallStartFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Arginfo kArginfo() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_X0 kX0() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_X5 kX5() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_AbQuota =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfUpdateBusFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AbQuota kAbQuota() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BusId kBusId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Client kClient() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IbQuota kIbQuota() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Fl =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfSetQosLutsFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Fl kFl() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Fmt kFmt() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lut kLut() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LutUsage kLutUsage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pnum kPnum() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Rt kRt() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_BwCtlEbi =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BwCtlEbi kBwCtlEbi() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BwCtlLlcc kBwCtlLlcc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BwCtlMnoc kBwCtlMnoc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CoreClkRate kCoreClkRate() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Crtc kCrtc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Params kParams() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PerPipeIbEbi kPerPipeIbEbi() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PerPipeIbLlcc kPerPipeIbLlcc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PerPipeIbMnoc kPerPipeIbMnoc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StopReq kStopReq() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UpdateBus kUpdateBus() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UpdateClk kUpdateClk() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_BwCtlEbi =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCalcCrtcFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BwCtlEbi kBwCtlEbi() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BwCtlLlcc kBwCtlLlcc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BwCtlMnoc kBwCtlMnoc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CoreClkRate kCoreClkRate() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Crtc kCrtc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IbEbi kIbEbi() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IbLlcc kIbLlcc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IbMnoc kIbMnoc() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_EvtlogTag =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SdeSdeEvtlogFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EvtlogTag kEvtlogTag() { return {}; }
+  void set_evtlog_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EvtlogTag::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TagId kTagId() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SdeTracingMarkWriteFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceName kTraceName() { return {}; }
+  void set_trace_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceType kTraceType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Value kValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceBegin kTraceBegin() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Code =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SignalGenerateFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Code kCode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Group kGroup() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Result kResult() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sig kSig() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Code =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SignalDeliverFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Code kCode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SaFlags kSaFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sig kSig() { return {}; }
+  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/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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SyncWaitFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Status kStatus() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Begin kBegin() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SyncTimelineFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Value kValue() { return {}; }
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SyncPtFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Timeline kTimeline() { return {}; }
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Value kValue() { return {}; }
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, 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/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,
+  };
+
+  using FieldMetadata_Flag =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ZeroFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Flag kFlag() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Value kValue() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TaskRenameFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Oldcomm kOldcomm() { return {}; }
+  void set_oldcomm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Oldcomm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Newcomm kNewcomm() { return {}; }
+  void set_newcomm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Newcomm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OomScoreAdj kOomScoreAdj() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TaskNewtaskFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Comm kComm() { return {}; }
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CloneFlags kCloneFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OomScoreAdj kOomScoreAdj() { return {}; }
+  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/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,
+  };
+
+  using FieldMetadata_Target =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      CdevUpdateFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Target kTarget() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  void set_type(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Type::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ThermalTemperatureFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Id kId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Temp kTemp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TempPrev kTempPrev() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThermalZone kThermalZone() { return {}; }
+  void set_thermal_zone(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ThermalZone::kFieldId, data, 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/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 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,
+  };
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmVmscanKswapdSleepFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nid kNid() { return {}; }
+  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=*/2, /*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(); }
+};
+
+class MmVmscanKswapdWakeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmVmscanKswapdWakeFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+    kOrderFieldNumber = 2,
+  };
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmVmscanKswapdWakeFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nid kNid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_NrReclaimed =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmVmscanDirectReclaimEndFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NrReclaimed kNrReclaimed() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmVmscanDirectReclaimBeginFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Order kOrder() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MayWritepage kMayWritepage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GfpFlags kGfpFlags() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Work =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueQueueWorkFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Work kWork() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Function kFunction() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Workqueue kWorkqueue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReqCpu kReqCpu() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cpu kCpu() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Work =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueExecuteStartFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Work kWork() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Function kFunction() { return {}; }
+  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=*/1, /*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(); }
+};
+
+class WorkqueueExecuteEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = WorkqueueExecuteEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kWorkFieldNumber = 1,
+  };
+
+  using FieldMetadata_Work =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueExecuteEndFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Work kWork() { return {}; }
+  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);
+  }
+};
+
+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,
+  };
+
+  using FieldMetadata_Work =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueActivateWorkFtraceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Work kWork() { return {}; }
+  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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CounterDescriptor kCounterDescriptor() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Counters kCounters() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuId kGpuId() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_CounterId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuCounterEvent_GpuCounter>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CounterId kCounterId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IntValue kIntValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DoubleValue kDoubleValue() { return {}; }
+  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 {
+
+enum GpuLog_Severity : int32_t;
+
+enum GpuLog_Severity : int32_t {
+  GpuLog_Severity_LOG_SEVERITY_UNSPECIFIED = 0,
+  GpuLog_Severity_LOG_SEVERITY_VERBOSE = 1,
+  GpuLog_Severity_LOG_SEVERITY_DEBUG = 2,
+  GpuLog_Severity_LOG_SEVERITY_INFO = 3,
+  GpuLog_Severity_LOG_SEVERITY_WARNING = 4,
+  GpuLog_Severity_LOG_SEVERITY_ERROR = 5,
+};
+
+const GpuLog_Severity GpuLog_Severity_MIN = GpuLog_Severity_LOG_SEVERITY_UNSPECIFIED;
+const GpuLog_Severity GpuLog_Severity_MAX = GpuLog_Severity_LOG_SEVERITY_ERROR;
+
+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,
+  };
+  using Severity = ::perfetto::protos::pbzero::GpuLog_Severity;
+  static const Severity LOG_SEVERITY_UNSPECIFIED = GpuLog_Severity_LOG_SEVERITY_UNSPECIFIED;
+  static const Severity LOG_SEVERITY_VERBOSE = GpuLog_Severity_LOG_SEVERITY_VERBOSE;
+  static const Severity LOG_SEVERITY_DEBUG = GpuLog_Severity_LOG_SEVERITY_DEBUG;
+  static const Severity LOG_SEVERITY_INFO = GpuLog_Severity_LOG_SEVERITY_INFO;
+  static const Severity LOG_SEVERITY_WARNING = GpuLog_Severity_LOG_SEVERITY_WARNING;
+  static const Severity LOG_SEVERITY_ERROR = GpuLog_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Severity kSeverity() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tag kTag() { return {}; }
+  void set_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LogMessage kLogMessage() { return {}; }
+  void set_log_message(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LogMessage::kFieldId, data, 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;
+enum InternedGpuRenderStageSpecification_RenderStageCategory : int32_t;
+enum InternedGraphicsContext_Api : int32_t;
+
+enum InternedGpuRenderStageSpecification_RenderStageCategory : int32_t {
+  InternedGpuRenderStageSpecification_RenderStageCategory_OTHER = 0,
+  InternedGpuRenderStageSpecification_RenderStageCategory_GRAPHICS = 1,
+  InternedGpuRenderStageSpecification_RenderStageCategory_COMPUTE = 2,
+};
+
+const InternedGpuRenderStageSpecification_RenderStageCategory InternedGpuRenderStageSpecification_RenderStageCategory_MIN = InternedGpuRenderStageSpecification_RenderStageCategory_OTHER;
+const InternedGpuRenderStageSpecification_RenderStageCategory InternedGpuRenderStageSpecification_RenderStageCategory_MAX = InternedGpuRenderStageSpecification_RenderStageCategory_COMPUTE;
+
+enum InternedGraphicsContext_Api : int32_t {
+  InternedGraphicsContext_Api_UNDEFINED = 0,
+  InternedGraphicsContext_Api_OPEN_GL = 1,
+  InternedGraphicsContext_Api_VULKAN = 2,
+  InternedGraphicsContext_Api_OPEN_CL = 3,
+};
+
+const InternedGraphicsContext_Api InternedGraphicsContext_Api_MIN = InternedGraphicsContext_Api_UNDEFINED;
+const InternedGraphicsContext_Api InternedGraphicsContext_Api_MAX = InternedGraphicsContext_Api_OPEN_CL;
+
+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,
+  };
+  using RenderStageCategory = ::perfetto::protos::pbzero::InternedGpuRenderStageSpecification_RenderStageCategory;
+  static const RenderStageCategory OTHER = InternedGpuRenderStageSpecification_RenderStageCategory_OTHER;
+  static const RenderStageCategory GRAPHICS = InternedGpuRenderStageSpecification_RenderStageCategory_GRAPHICS;
+  static const RenderStageCategory COMPUTE = InternedGpuRenderStageSpecification_RenderStageCategory_COMPUTE;
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedGpuRenderStageSpecification>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Iid kIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Description kDescription() { return {}; }
+  void set_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Description::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Category kCategory() { return {}; }
+  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,
+  };
+  using Api = ::perfetto::protos::pbzero::InternedGraphicsContext_Api;
+  static const Api UNDEFINED = InternedGraphicsContext_Api_UNDEFINED;
+  static const Api OPEN_GL = InternedGraphicsContext_Api_OPEN_GL;
+  static const Api VULKAN = InternedGraphicsContext_Api_VULKAN;
+  static const Api OPEN_CL = InternedGraphicsContext_Api_OPEN_CL;
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedGraphicsContext>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Iid kIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Api kApi() { return {}; }
+  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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EventId kEventId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Duration kDuration() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HwQueueIid kHwQueueIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StageIid kStageIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuId kGpuId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Context kContext() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RenderTargetHandle kRenderTargetHandle() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SubmissionId kSubmissionId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExtraData kExtraData() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RenderPassHandle kRenderPassHandle() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RenderSubpassIndexMask kRenderSubpassIndexMask() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CommandBufferHandle kCommandBufferHandle() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Specifications kSpecifications() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HwQueueId kHwQueueId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StageId kStageId() { return {}; }
+  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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ContextSpec kContextSpec() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HwQueue kHwQueue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Stage kStage() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuRenderStageEvent_Specifications_Description>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Description kDescription() { return {}; }
+  void set_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Description::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent_Specifications_ContextSpec>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Context kContext() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuRenderStageEvent_ExtraData>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Value kValue() { return {}; }
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, 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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VkDebugUtilsObjectName kVkDebugUtilsObjectName() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VkQueueSubmit kVkQueueSubmit() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_DurationNs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanApiEvent_VkQueueSubmit>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DurationNs kDurationNs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tid kTid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VkQueue kVkQueue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VkCommandBuffers kVkCommandBuffers() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SubmissionId kSubmissionId() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VulkanApiEvent_VkDebugUtilsObjectName>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VkDevice kVkDevice() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ObjectType kObjectType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Object kObject() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ObjectName kObjectName() { return {}; }
+  void set_object_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ObjectName::kFieldId, data, 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;
+enum VulkanMemoryEvent_AllocationScope : int32_t;
+enum VulkanMemoryEvent_Operation : int32_t;
+enum VulkanMemoryEvent_Source : int32_t;
+
+enum VulkanMemoryEvent_Source : int32_t {
+  VulkanMemoryEvent_Source_SOURCE_UNSPECIFIED = 0,
+  VulkanMemoryEvent_Source_SOURCE_DRIVER = 1,
+  VulkanMemoryEvent_Source_SOURCE_DEVICE = 2,
+  VulkanMemoryEvent_Source_SOURCE_DEVICE_MEMORY = 3,
+  VulkanMemoryEvent_Source_SOURCE_BUFFER = 4,
+  VulkanMemoryEvent_Source_SOURCE_IMAGE = 5,
+};
+
+const VulkanMemoryEvent_Source VulkanMemoryEvent_Source_MIN = VulkanMemoryEvent_Source_SOURCE_UNSPECIFIED;
+const VulkanMemoryEvent_Source VulkanMemoryEvent_Source_MAX = VulkanMemoryEvent_Source_SOURCE_IMAGE;
+
+enum VulkanMemoryEvent_Operation : int32_t {
+  VulkanMemoryEvent_Operation_OP_UNSPECIFIED = 0,
+  VulkanMemoryEvent_Operation_OP_CREATE = 1,
+  VulkanMemoryEvent_Operation_OP_DESTROY = 2,
+  VulkanMemoryEvent_Operation_OP_BIND = 3,
+  VulkanMemoryEvent_Operation_OP_DESTROY_BOUND = 4,
+  VulkanMemoryEvent_Operation_OP_ANNOTATIONS = 5,
+};
+
+const VulkanMemoryEvent_Operation VulkanMemoryEvent_Operation_MIN = VulkanMemoryEvent_Operation_OP_UNSPECIFIED;
+const VulkanMemoryEvent_Operation VulkanMemoryEvent_Operation_MAX = VulkanMemoryEvent_Operation_OP_ANNOTATIONS;
+
+enum VulkanMemoryEvent_AllocationScope : int32_t {
+  VulkanMemoryEvent_AllocationScope_SCOPE_UNSPECIFIED = 0,
+  VulkanMemoryEvent_AllocationScope_SCOPE_COMMAND = 1,
+  VulkanMemoryEvent_AllocationScope_SCOPE_OBJECT = 2,
+  VulkanMemoryEvent_AllocationScope_SCOPE_CACHE = 3,
+  VulkanMemoryEvent_AllocationScope_SCOPE_DEVICE = 4,
+  VulkanMemoryEvent_AllocationScope_SCOPE_INSTANCE = 5,
+};
+
+const VulkanMemoryEvent_AllocationScope VulkanMemoryEvent_AllocationScope_MIN = VulkanMemoryEvent_AllocationScope_SCOPE_UNSPECIFIED;
+const VulkanMemoryEvent_AllocationScope VulkanMemoryEvent_AllocationScope_MAX = VulkanMemoryEvent_AllocationScope_SCOPE_INSTANCE;
+
+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,
+  };
+  using Source = ::perfetto::protos::pbzero::VulkanMemoryEvent_Source;
+  using Operation = ::perfetto::protos::pbzero::VulkanMemoryEvent_Operation;
+  using AllocationScope = ::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope;
+  static const Source SOURCE_UNSPECIFIED = VulkanMemoryEvent_Source_SOURCE_UNSPECIFIED;
+  static const Source SOURCE_DRIVER = VulkanMemoryEvent_Source_SOURCE_DRIVER;
+  static const Source SOURCE_DEVICE = VulkanMemoryEvent_Source_SOURCE_DEVICE;
+  static const Source SOURCE_DEVICE_MEMORY = VulkanMemoryEvent_Source_SOURCE_DEVICE_MEMORY;
+  static const Source SOURCE_BUFFER = VulkanMemoryEvent_Source_SOURCE_BUFFER;
+  static const Source SOURCE_IMAGE = VulkanMemoryEvent_Source_SOURCE_IMAGE;
+  static const Operation OP_UNSPECIFIED = VulkanMemoryEvent_Operation_OP_UNSPECIFIED;
+  static const Operation OP_CREATE = VulkanMemoryEvent_Operation_OP_CREATE;
+  static const Operation OP_DESTROY = VulkanMemoryEvent_Operation_OP_DESTROY;
+  static const Operation OP_BIND = VulkanMemoryEvent_Operation_OP_BIND;
+  static const Operation OP_DESTROY_BOUND = VulkanMemoryEvent_Operation_OP_DESTROY_BOUND;
+  static const Operation OP_ANNOTATIONS = VulkanMemoryEvent_Operation_OP_ANNOTATIONS;
+  static const AllocationScope SCOPE_UNSPECIFIED = VulkanMemoryEvent_AllocationScope_SCOPE_UNSPECIFIED;
+  static const AllocationScope SCOPE_COMMAND = VulkanMemoryEvent_AllocationScope_SCOPE_COMMAND;
+  static const AllocationScope SCOPE_OBJECT = VulkanMemoryEvent_AllocationScope_SCOPE_OBJECT;
+  static const AllocationScope SCOPE_CACHE = VulkanMemoryEvent_AllocationScope_SCOPE_CACHE;
+  static const AllocationScope SCOPE_DEVICE = VulkanMemoryEvent_AllocationScope_SCOPE_DEVICE;
+  static const AllocationScope SCOPE_INSTANCE = VulkanMemoryEvent_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Source kSource() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Operation kOperation() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Timestamp kTimestamp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MemoryAddress kMemoryAddress() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MemorySize kMemorySize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CallerIid kCallerIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllocationScope kAllocationScope() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Annotations kAnnotations() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Device kDevice() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DeviceMemory kDeviceMemory() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MemoryType kMemoryType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Heap kHeap() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ObjectHandle kObjectHandle() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_KeyIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanMemoryEventAnnotation>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_KeyIid kKeyIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IntValue kIntValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DoubleValue kDoubleValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StringIid kStringIid() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_PackageName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DeobfuscationMapping>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PackageName kPackageName() { return {}; }
+  void set_package_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_PackageName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VersionCode kVersionCode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ObfuscatedClasses kObfuscatedClasses() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_ObfuscatedName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ObfuscatedClass>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ObfuscatedName kObfuscatedName() { return {}; }
+  void set_obfuscated_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ObfuscatedName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DeobfuscatedName kDeobfuscatedName() { return {}; }
+  void set_deobfuscated_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DeobfuscatedName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ObfuscatedMembers kObfuscatedMembers() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ObfuscatedMethods kObfuscatedMethods() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_ObfuscatedName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ObfuscatedMember>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ObfuscatedName kObfuscatedName() { return {}; }
+  void set_obfuscated_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ObfuscatedName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DeobfuscatedName kDeobfuscatedName() { return {}; }
+  void set_deobfuscated_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DeobfuscatedName::kFieldId, data, 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
+// 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,
+  };
+
+  using FieldMetadata_PackageName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DeobfuscationMapping>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PackageName kPackageName() { return {}; }
+  void set_package_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_PackageName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VersionCode kVersionCode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ObfuscatedClasses kObfuscatedClasses() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_ObfuscatedName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ObfuscatedClass>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ObfuscatedName kObfuscatedName() { return {}; }
+  void set_obfuscated_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ObfuscatedName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DeobfuscatedName kDeobfuscatedName() { return {}; }
+  void set_deobfuscated_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DeobfuscatedName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ObfuscatedMembers kObfuscatedMembers() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ObfuscatedMethods kObfuscatedMethods() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_ObfuscatedName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ObfuscatedMember>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ObfuscatedName kObfuscatedName() { return {}; }
+  void set_obfuscated_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ObfuscatedName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DeobfuscatedName kDeobfuscatedName() { return {}; }
+  void set_deobfuscated_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DeobfuscatedName::kFieldId, data, 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.
+// 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;
+enum HeapGraphRoot_Type : int32_t;
+enum HeapGraphType_Kind : int32_t;
+
+enum HeapGraphType_Kind : int32_t {
+  HeapGraphType_Kind_KIND_UNKNOWN = 0,
+  HeapGraphType_Kind_KIND_NORMAL = 1,
+  HeapGraphType_Kind_KIND_NOREFERENCES = 2,
+  HeapGraphType_Kind_KIND_STRING = 3,
+  HeapGraphType_Kind_KIND_ARRAY = 4,
+  HeapGraphType_Kind_KIND_CLASS = 5,
+  HeapGraphType_Kind_KIND_CLASSLOADER = 6,
+  HeapGraphType_Kind_KIND_DEXCACHE = 7,
+  HeapGraphType_Kind_KIND_SOFT_REFERENCE = 8,
+  HeapGraphType_Kind_KIND_WEAK_REFERENCE = 9,
+  HeapGraphType_Kind_KIND_FINALIZER_REFERENCE = 10,
+  HeapGraphType_Kind_KIND_PHANTOM_REFERENCE = 11,
+};
+
+const HeapGraphType_Kind HeapGraphType_Kind_MIN = HeapGraphType_Kind_KIND_UNKNOWN;
+const HeapGraphType_Kind HeapGraphType_Kind_MAX = HeapGraphType_Kind_KIND_PHANTOM_REFERENCE;
+
+enum HeapGraphRoot_Type : int32_t {
+  HeapGraphRoot_Type_ROOT_UNKNOWN = 0,
+  HeapGraphRoot_Type_ROOT_JNI_GLOBAL = 1,
+  HeapGraphRoot_Type_ROOT_JNI_LOCAL = 2,
+  HeapGraphRoot_Type_ROOT_JAVA_FRAME = 3,
+  HeapGraphRoot_Type_ROOT_NATIVE_STACK = 4,
+  HeapGraphRoot_Type_ROOT_STICKY_CLASS = 5,
+  HeapGraphRoot_Type_ROOT_THREAD_BLOCK = 6,
+  HeapGraphRoot_Type_ROOT_MONITOR_USED = 7,
+  HeapGraphRoot_Type_ROOT_THREAD_OBJECT = 8,
+  HeapGraphRoot_Type_ROOT_INTERNED_STRING = 9,
+  HeapGraphRoot_Type_ROOT_FINALIZING = 10,
+  HeapGraphRoot_Type_ROOT_DEBUGGER = 11,
+  HeapGraphRoot_Type_ROOT_REFERENCE_CLEANUP = 12,
+  HeapGraphRoot_Type_ROOT_VM_INTERNAL = 13,
+  HeapGraphRoot_Type_ROOT_JNI_MONITOR = 14,
+};
+
+const HeapGraphRoot_Type HeapGraphRoot_Type_MIN = HeapGraphRoot_Type_ROOT_UNKNOWN;
+const HeapGraphRoot_Type HeapGraphRoot_Type_MAX = HeapGraphRoot_Type_ROOT_JNI_MONITOR;
+
+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,
+  };
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      HeapGraph>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Objects kObjects() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Roots kRoots() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Types kTypes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FieldNames kFieldNames() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LocationNames kLocationNames() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Continued kContinued() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Index kIndex() { return {}; }
+  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=*/7, /*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); }
+};
+
+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,
+  };
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphObject>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Id kId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IdDelta kIdDelta() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TypeId kTypeId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SelfSize kSelfSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReferenceFieldIdBase kReferenceFieldIdBase() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReferenceFieldId kReferenceFieldId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReferenceObjectId kReferenceObjectId() { return {}; }
+  void set_reference_object_id(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_ReferenceObjectId::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+};
+
+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,
+  };
+  using Kind = ::perfetto::protos::pbzero::HeapGraphType_Kind;
+  static const Kind KIND_UNKNOWN = HeapGraphType_Kind_KIND_UNKNOWN;
+  static const Kind KIND_NORMAL = HeapGraphType_Kind_KIND_NORMAL;
+  static const Kind KIND_NOREFERENCES = HeapGraphType_Kind_KIND_NOREFERENCES;
+  static const Kind KIND_STRING = HeapGraphType_Kind_KIND_STRING;
+  static const Kind KIND_ARRAY = HeapGraphType_Kind_KIND_ARRAY;
+  static const Kind KIND_CLASS = HeapGraphType_Kind_KIND_CLASS;
+  static const Kind KIND_CLASSLOADER = HeapGraphType_Kind_KIND_CLASSLOADER;
+  static const Kind KIND_DEXCACHE = HeapGraphType_Kind_KIND_DEXCACHE;
+  static const Kind KIND_SOFT_REFERENCE = HeapGraphType_Kind_KIND_SOFT_REFERENCE;
+  static const Kind KIND_WEAK_REFERENCE = HeapGraphType_Kind_KIND_WEAK_REFERENCE;
+  static const Kind KIND_FINALIZER_REFERENCE = HeapGraphType_Kind_KIND_FINALIZER_REFERENCE;
+  static const Kind KIND_PHANTOM_REFERENCE = HeapGraphType_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Id kId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LocationId kLocationId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClassName kClassName() { return {}; }
+  void set_class_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ClassName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ObjectSize kObjectSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SuperclassId kSuperclassId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReferenceFieldId kReferenceFieldId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Kind kKind() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClassloaderId kClassloaderId() { return {}; }
+  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,
+  };
+  using Type = ::perfetto::protos::pbzero::HeapGraphRoot_Type;
+  static const Type ROOT_UNKNOWN = HeapGraphRoot_Type_ROOT_UNKNOWN;
+  static const Type ROOT_JNI_GLOBAL = HeapGraphRoot_Type_ROOT_JNI_GLOBAL;
+  static const Type ROOT_JNI_LOCAL = HeapGraphRoot_Type_ROOT_JNI_LOCAL;
+  static const Type ROOT_JAVA_FRAME = HeapGraphRoot_Type_ROOT_JAVA_FRAME;
+  static const Type ROOT_NATIVE_STACK = HeapGraphRoot_Type_ROOT_NATIVE_STACK;
+  static const Type ROOT_STICKY_CLASS = HeapGraphRoot_Type_ROOT_STICKY_CLASS;
+  static const Type ROOT_THREAD_BLOCK = HeapGraphRoot_Type_ROOT_THREAD_BLOCK;
+  static const Type ROOT_MONITOR_USED = HeapGraphRoot_Type_ROOT_MONITOR_USED;
+  static const Type ROOT_THREAD_OBJECT = HeapGraphRoot_Type_ROOT_THREAD_OBJECT;
+  static const Type ROOT_INTERNED_STRING = HeapGraphRoot_Type_ROOT_INTERNED_STRING;
+  static const Type ROOT_FINALIZING = HeapGraphRoot_Type_ROOT_FINALIZING;
+  static const Type ROOT_DEBUGGER = HeapGraphRoot_Type_ROOT_DEBUGGER;
+  static const Type ROOT_REFERENCE_CLEANUP = HeapGraphRoot_Type_ROOT_REFERENCE_CLEANUP;
+  static const Type ROOT_VM_INTERNAL = HeapGraphRoot_Type_ROOT_VM_INTERNAL;
+  static const Type ROOT_JNI_MONITOR = HeapGraphRoot_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ObjectIds kObjectIds() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RootType kRootType() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Callstack>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Iid kIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FrameIds kFrameIds() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Frame>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Iid kIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FunctionNameId kFunctionNameId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MappingId kMappingId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RelPc kRelPc() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Mapping>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Iid kIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BuildId kBuildId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExactOffset kExactOffset() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StartOffset kStartOffset() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Start kStart() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_End kEnd() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LoadBias kLoadBias() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PathStringIds kPathStringIds() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Path =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ModuleSymbols>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Path kPath() { return {}; }
+  void set_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Path::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BuildId kBuildId() { return {}; }
+  void set_build_id(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_BuildId::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AddressSymbols kAddressSymbols() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Address =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AddressSymbols>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Address kAddress() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Lines kLines() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_FunctionName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Line>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FunctionName kFunctionName() { return {}; }
+  void set_function_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FunctionName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SourceFileName kSourceFileName() { return {}; }
+  void set_source_file_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SourceFileName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LineNumber kLineNumber() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_FrameIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfiledFrameSymbols>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FrameIid kFrameIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FunctionNameId kFunctionNameId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FileNameId kFileNameId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LineNumber kLineNumber() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedString>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Iid kIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Str kStr() { return {}; }
+  void set_str(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Str::kFieldId, data, 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;
+enum PerfSample_ProducerEvent_DataSourceStopReason : int32_t;
+enum PerfSample_SampleSkipReason : int32_t;
+enum ProfilePacket_ProcessHeapSamples_ClientError : int32_t;
+enum Profiling_CpuMode : int32_t;
+enum Profiling_StackUnwindError : int32_t;
+
+enum PerfSample_SampleSkipReason : int32_t {
+  PerfSample_SampleSkipReason_PROFILER_SKIP_UNKNOWN = 0,
+  PerfSample_SampleSkipReason_PROFILER_SKIP_READ_STAGE = 1,
+  PerfSample_SampleSkipReason_PROFILER_SKIP_UNWIND_STAGE = 2,
+  PerfSample_SampleSkipReason_PROFILER_SKIP_UNWIND_ENQUEUE = 3,
+};
+
+const PerfSample_SampleSkipReason PerfSample_SampleSkipReason_MIN = PerfSample_SampleSkipReason_PROFILER_SKIP_UNKNOWN;
+const PerfSample_SampleSkipReason PerfSample_SampleSkipReason_MAX = PerfSample_SampleSkipReason_PROFILER_SKIP_UNWIND_ENQUEUE;
+
+enum PerfSample_ProducerEvent_DataSourceStopReason : int32_t {
+  PerfSample_ProducerEvent_DataSourceStopReason_PROFILER_STOP_UNKNOWN = 0,
+  PerfSample_ProducerEvent_DataSourceStopReason_PROFILER_STOP_GUARDRAIL = 1,
+};
+
+const PerfSample_ProducerEvent_DataSourceStopReason PerfSample_ProducerEvent_DataSourceStopReason_MIN = PerfSample_ProducerEvent_DataSourceStopReason_PROFILER_STOP_UNKNOWN;
+const PerfSample_ProducerEvent_DataSourceStopReason PerfSample_ProducerEvent_DataSourceStopReason_MAX = PerfSample_ProducerEvent_DataSourceStopReason_PROFILER_STOP_GUARDRAIL;
+
+enum Profiling_CpuMode : int32_t {
+  Profiling_CpuMode_MODE_UNKNOWN = 0,
+  Profiling_CpuMode_MODE_KERNEL = 1,
+  Profiling_CpuMode_MODE_USER = 2,
+  Profiling_CpuMode_MODE_HYPERVISOR = 3,
+  Profiling_CpuMode_MODE_GUEST_KERNEL = 4,
+  Profiling_CpuMode_MODE_GUEST_USER = 5,
+};
+
+const Profiling_CpuMode Profiling_CpuMode_MIN = Profiling_CpuMode_MODE_UNKNOWN;
+const Profiling_CpuMode Profiling_CpuMode_MAX = Profiling_CpuMode_MODE_GUEST_USER;
+
+enum Profiling_StackUnwindError : int32_t {
+  Profiling_StackUnwindError_UNWIND_ERROR_UNKNOWN = 0,
+  Profiling_StackUnwindError_UNWIND_ERROR_NONE = 1,
+  Profiling_StackUnwindError_UNWIND_ERROR_MEMORY_INVALID = 2,
+  Profiling_StackUnwindError_UNWIND_ERROR_UNWIND_INFO = 3,
+  Profiling_StackUnwindError_UNWIND_ERROR_UNSUPPORTED = 4,
+  Profiling_StackUnwindError_UNWIND_ERROR_INVALID_MAP = 5,
+  Profiling_StackUnwindError_UNWIND_ERROR_MAX_FRAMES_EXCEEDED = 6,
+  Profiling_StackUnwindError_UNWIND_ERROR_REPEATED_FRAME = 7,
+  Profiling_StackUnwindError_UNWIND_ERROR_INVALID_ELF = 8,
+  Profiling_StackUnwindError_UNWIND_ERROR_SYSTEM_CALL = 9,
+  Profiling_StackUnwindError_UNWIND_ERROR_THREAD_TIMEOUT = 10,
+  Profiling_StackUnwindError_UNWIND_ERROR_THREAD_DOES_NOT_EXIST = 11,
+};
+
+const Profiling_StackUnwindError Profiling_StackUnwindError_MIN = Profiling_StackUnwindError_UNWIND_ERROR_UNKNOWN;
+const Profiling_StackUnwindError Profiling_StackUnwindError_MAX = Profiling_StackUnwindError_UNWIND_ERROR_THREAD_DOES_NOT_EXIST;
+
+enum ProfilePacket_ProcessHeapSamples_ClientError : int32_t {
+  ProfilePacket_ProcessHeapSamples_ClientError_CLIENT_ERROR_NONE = 0,
+  ProfilePacket_ProcessHeapSamples_ClientError_CLIENT_ERROR_HIT_TIMEOUT = 1,
+  ProfilePacket_ProcessHeapSamples_ClientError_CLIENT_ERROR_INVALID_STACK_BOUNDS = 2,
+};
+
+const ProfilePacket_ProcessHeapSamples_ClientError ProfilePacket_ProcessHeapSamples_ClientError_MIN = ProfilePacket_ProcessHeapSamples_ClientError_CLIENT_ERROR_NONE;
+const ProfilePacket_ProcessHeapSamples_ClientError ProfilePacket_ProcessHeapSamples_ClientError_MAX = ProfilePacket_ProcessHeapSamples_ClientError_CLIENT_ERROR_INVALID_STACK_BOUNDS;
+
+class PerfSampleDefaults_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*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(); }
+};
+
+class PerfSampleDefaults : public ::protozero::Message {
+ public:
+  using Decoder = PerfSampleDefaults_Decoder;
+  enum : int32_t {
+    kTimebaseFieldNumber = 1,
+  };
+
+  using FieldMetadata_Timebase =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfEvents_Timebase,
+      PerfSampleDefaults>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Timebase kTimebase() { return {}; }
+  template <typename T = PerfEvents_Timebase> T* set_timebase() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+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,
+  };
+  using ProducerEvent = ::perfetto::protos::pbzero::PerfSample_ProducerEvent;
+  using SampleSkipReason = ::perfetto::protos::pbzero::PerfSample_SampleSkipReason;
+  static const SampleSkipReason PROFILER_SKIP_UNKNOWN = PerfSample_SampleSkipReason_PROFILER_SKIP_UNKNOWN;
+  static const SampleSkipReason PROFILER_SKIP_READ_STAGE = PerfSample_SampleSkipReason_PROFILER_SKIP_READ_STAGE;
+  static const SampleSkipReason PROFILER_SKIP_UNWIND_STAGE = PerfSample_SampleSkipReason_PROFILER_SKIP_UNWIND_STAGE;
+  static const SampleSkipReason PROFILER_SKIP_UNWIND_ENQUEUE = PerfSample_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cpu kCpu() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tid kTid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuMode kCpuMode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TimebaseCount kTimebaseCount() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CallstackIid kCallstackIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UnwindError kUnwindError() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_KernelRecordsLost kKernelRecordsLost() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SampleSkippedReason kSampleSkippedReason() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProducerEvent kProducerEvent() { return {}; }
+  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,
+  };
+  using DataSourceStopReason = ::perfetto::protos::pbzero::PerfSample_ProducerEvent_DataSourceStopReason;
+  static const DataSourceStopReason PROFILER_STOP_UNKNOWN = PerfSample_ProducerEvent_DataSourceStopReason_PROFILER_STOP_UNKNOWN;
+  static const DataSourceStopReason PROFILER_STOP_GUARDRAIL = PerfSample_ProducerEvent_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SourceStopReason kSourceStopReason() { return {}; }
+  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;
+  using CpuMode = ::perfetto::protos::pbzero::Profiling_CpuMode;
+  using StackUnwindError = ::perfetto::protos::pbzero::Profiling_StackUnwindError;
+  static const CpuMode MODE_UNKNOWN = Profiling_CpuMode_MODE_UNKNOWN;
+  static const CpuMode MODE_KERNEL = Profiling_CpuMode_MODE_KERNEL;
+  static const CpuMode MODE_USER = Profiling_CpuMode_MODE_USER;
+  static const CpuMode MODE_HYPERVISOR = Profiling_CpuMode_MODE_HYPERVISOR;
+  static const CpuMode MODE_GUEST_KERNEL = Profiling_CpuMode_MODE_GUEST_KERNEL;
+  static const CpuMode MODE_GUEST_USER = Profiling_CpuMode_MODE_GUEST_USER;
+  static const StackUnwindError UNWIND_ERROR_UNKNOWN = Profiling_StackUnwindError_UNWIND_ERROR_UNKNOWN;
+  static const StackUnwindError UNWIND_ERROR_NONE = Profiling_StackUnwindError_UNWIND_ERROR_NONE;
+  static const StackUnwindError UNWIND_ERROR_MEMORY_INVALID = Profiling_StackUnwindError_UNWIND_ERROR_MEMORY_INVALID;
+  static const StackUnwindError UNWIND_ERROR_UNWIND_INFO = Profiling_StackUnwindError_UNWIND_ERROR_UNWIND_INFO;
+  static const StackUnwindError UNWIND_ERROR_UNSUPPORTED = Profiling_StackUnwindError_UNWIND_ERROR_UNSUPPORTED;
+  static const StackUnwindError UNWIND_ERROR_INVALID_MAP = Profiling_StackUnwindError_UNWIND_ERROR_INVALID_MAP;
+  static const StackUnwindError UNWIND_ERROR_MAX_FRAMES_EXCEEDED = Profiling_StackUnwindError_UNWIND_ERROR_MAX_FRAMES_EXCEEDED;
+  static const StackUnwindError UNWIND_ERROR_REPEATED_FRAME = Profiling_StackUnwindError_UNWIND_ERROR_REPEATED_FRAME;
+  static const StackUnwindError UNWIND_ERROR_INVALID_ELF = Profiling_StackUnwindError_UNWIND_ERROR_INVALID_ELF;
+  static const StackUnwindError UNWIND_ERROR_SYSTEM_CALL = Profiling_StackUnwindError_UNWIND_ERROR_SYSTEM_CALL;
+  static const StackUnwindError UNWIND_ERROR_THREAD_TIMEOUT = Profiling_StackUnwindError_UNWIND_ERROR_THREAD_TIMEOUT;
+  static const StackUnwindError UNWIND_ERROR_THREAD_DOES_NOT_EXIST = Profiling_StackUnwindError_UNWIND_ERROR_THREAD_DOES_NOT_EXIST;
+};
+
+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,
+  };
+
+  using FieldMetadata_CallstackIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      StreamingProfilePacket>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CallstackIid kCallstackIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TimestampDeltaUs kTimestampDeltaUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessPriority kProcessPriority() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Address =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      StreamingFree>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Address kAddress() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HeapId kHeapId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SequenceNumber kSequenceNumber() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Address =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      StreamingAllocation>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Address kAddress() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Size kSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SampleSize kSampleSize() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClockMonotonicCoarseTimestamp kClockMonotonicCoarseTimestamp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HeapId kHeapId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SequenceNumber kSequenceNumber() { return {}; }
+  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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Strings kStrings() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mappings kMappings() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Frames kFrames() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Callstacks kCallstacks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessDumps kProcessDumps() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Continued kContinued() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Index kIndex() { return {}; }
+  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,
+  };
+  using ClientError = ::perfetto::protos::pbzero::ProfilePacket_ProcessHeapSamples_ClientError;
+  static const ClientError CLIENT_ERROR_NONE = ProfilePacket_ProcessHeapSamples_ClientError_CLIENT_ERROR_NONE;
+  static const ClientError CLIENT_ERROR_HIT_TIMEOUT = ProfilePacket_ProcessHeapSamples_ClientError_CLIENT_ERROR_HIT_TIMEOUT;
+  static const ClientError CLIENT_ERROR_INVALID_STACK_BOUNDS = ProfilePacket_ProcessHeapSamples_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FromStartup kFromStartup() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RejectedConcurrent kRejectedConcurrent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Disconnected kDisconnected() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BufferOverran kBufferOverran() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClientError kClientError() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BufferCorrupted kBufferCorrupted() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HitGuardrail kHitGuardrail() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HeapName kHeapName() { return {}; }
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SamplingIntervalBytes kSamplingIntervalBytes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OrigSamplingIntervalBytes kOrigSamplingIntervalBytes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Timestamp kTimestamp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Stats kStats() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Samples kSamples() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_UnwindingErrors =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_ProcessStats>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UnwindingErrors kUnwindingErrors() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HeapSamples kHeapSamples() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MapReparses kMapReparses() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UnwindingTimeUs kUnwindingTimeUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TotalUnwindingTimeUs kTotalUnwindingTimeUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClientSpinlockBlockedUs kClientSpinlockBlockedUs() { return {}; }
+  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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Buckets kBuckets() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_UpperLimit =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_Histogram_Bucket>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UpperLimit kUpperLimit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MaxBucket kMaxBucket() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Count kCount() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_CallstackId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_HeapSample>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CallstackId kCallstackId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SelfAllocated kSelfAllocated() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SelfFreed kSelfFreed() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SelfMax kSelfMax() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SelfMaxCount kSelfMaxCount() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Timestamp kTimestamp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllocCount kAllocCount() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FreeCount kFreeCount() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmapsPacket>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Entries kEntries() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Path =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SmapsEntry>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Path kPath() { return {}; }
+  void set_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Path::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SizeKb kSizeKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PrivateDirtyKb kPrivateDirtyKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SwapKb kSwapKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FileName kFileName() { return {}; }
+  void set_file_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FileName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StartAddress kStartAddress() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ModuleTimestamp kModuleTimestamp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ModuleDebugid kModuleDebugid() { return {}; }
+  void set_module_debugid(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ModuleDebugid::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ModuleDebugPath kModuleDebugPath() { return {}; }
+  void set_module_debug_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ModuleDebugPath::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProtectionFlags kProtectionFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PrivateCleanResidentKb kPrivateCleanResidentKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SharedDirtyResidentKb kSharedDirtyResidentKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SharedCleanResidentKb kSharedCleanResidentKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LockedKb kLockedKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProportionalResidentKb kProportionalResidentKb() { return {}; }
+  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_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 {
+
+enum ChromeApplicationStateInfo_ChromeApplicationState : int32_t;
+
+enum ChromeApplicationStateInfo_ChromeApplicationState : int32_t {
+  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,
+};
+
+const ChromeApplicationStateInfo_ChromeApplicationState ChromeApplicationStateInfo_ChromeApplicationState_MIN = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_UNKNOWN;
+const ChromeApplicationStateInfo_ChromeApplicationState ChromeApplicationStateInfo_ChromeApplicationState_MAX = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES;
+
+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,
+  };
+  using ChromeApplicationState = ::perfetto::protos::pbzero::ChromeApplicationStateInfo_ChromeApplicationState;
+  static const ChromeApplicationState APPLICATION_STATE_UNKNOWN = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_UNKNOWN;
+  static const ChromeApplicationState APPLICATION_STATE_HAS_RUNNING_ACTIVITIES = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
+  static const ChromeApplicationState APPLICATION_STATE_HAS_PAUSED_ACTIVITIES = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_PAUSED_ACTIVITIES;
+  static const ChromeApplicationState APPLICATION_STATE_HAS_STOPPED_ACTIVITIES = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_STOPPED_ACTIVITIES;
+  static const ChromeApplicationState APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES = ChromeApplicationStateInfo_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ApplicationState kApplicationState() { return {}; }
+  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;
+enum BeginFrameArgs_BeginFrameArgsType : int32_t;
+enum BeginImplFrameArgs_State : int32_t;
+enum ChromeCompositorSchedulerAction : int32_t;
+enum ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode : int32_t;
+enum ChromeCompositorStateMachine_MajorState_BeginImplFrameState : int32_t;
+enum ChromeCompositorStateMachine_MajorState_BeginMainFrameState : int32_t;
+enum ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState : int32_t;
+enum ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState : int32_t;
+enum ChromeCompositorStateMachine_MinorState_ScrollHandlerState : int32_t;
+enum ChromeCompositorStateMachine_MinorState_TreePriority : int32_t;
+
+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,
+};
+
+const ChromeCompositorSchedulerAction ChromeCompositorSchedulerAction_MIN = CC_SCHEDULER_ACTION_UNSPECIFIED;
+const ChromeCompositorSchedulerAction ChromeCompositorSchedulerAction_MAX = CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON;
+
+enum BeginImplFrameArgs_State : int32_t {
+  BeginImplFrameArgs_State_BEGIN_FRAME_FINISHED = 0,
+  BeginImplFrameArgs_State_BEGIN_FRAME_USING = 1,
+};
+
+const BeginImplFrameArgs_State BeginImplFrameArgs_State_MIN = BeginImplFrameArgs_State_BEGIN_FRAME_FINISHED;
+const BeginImplFrameArgs_State BeginImplFrameArgs_State_MAX = BeginImplFrameArgs_State_BEGIN_FRAME_USING;
+
+enum BeginFrameArgs_BeginFrameArgsType : int32_t {
+  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,
+};
+
+const BeginFrameArgs_BeginFrameArgsType BeginFrameArgs_BeginFrameArgsType_MIN = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED;
+const BeginFrameArgs_BeginFrameArgsType BeginFrameArgs_BeginFrameArgsType_MAX = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_MISSED;
+
+enum ChromeCompositorStateMachine_MinorState_TreePriority : int32_t {
+  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,
+};
+
+const ChromeCompositorStateMachine_MinorState_TreePriority ChromeCompositorStateMachine_MinorState_TreePriority_MIN = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_UNSPECIFIED;
+const ChromeCompositorStateMachine_MinorState_TreePriority ChromeCompositorStateMachine_MinorState_TreePriority_MAX = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY;
+
+enum ChromeCompositorStateMachine_MinorState_ScrollHandlerState : int32_t {
+  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,
+};
+
+const ChromeCompositorStateMachine_MinorState_ScrollHandlerState ChromeCompositorStateMachine_MinorState_ScrollHandlerState_MIN = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_HANDLER_UNSPECIFIED;
+const ChromeCompositorStateMachine_MinorState_ScrollHandlerState ChromeCompositorStateMachine_MinorState_ScrollHandlerState_MAX = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER;
+
+enum ChromeCompositorStateMachine_MajorState_BeginImplFrameState : int32_t {
+  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,
+};
+
+const ChromeCompositorStateMachine_MajorState_BeginImplFrameState ChromeCompositorStateMachine_MajorState_BeginImplFrameState_MIN = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_UNSPECIFIED;
+const ChromeCompositorStateMachine_MajorState_BeginImplFrameState ChromeCompositorStateMachine_MajorState_BeginImplFrameState_MAX = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_DEADLINE;
+
+enum ChromeCompositorStateMachine_MajorState_BeginMainFrameState : int32_t {
+  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,
+};
+
+const ChromeCompositorStateMachine_MajorState_BeginMainFrameState ChromeCompositorStateMachine_MajorState_BeginMainFrameState_MIN = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_UNSPECIFIED;
+const ChromeCompositorStateMachine_MajorState_BeginMainFrameState ChromeCompositorStateMachine_MajorState_BeginMainFrameState_MAX = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_READY_TO_COMMIT;
+
+enum ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState : int32_t {
+  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,
+};
+
+const ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_MIN = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_UNSPECIFIED;
+const ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_MAX = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION;
+
+enum ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState : int32_t {
+  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,
+};
+
+const ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_MIN = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_UNSPECIFIED;
+const ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_MAX = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_DRAW;
+
+enum ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode : int32_t {
+  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,
+};
+
+const ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_MIN = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_UNSPECIFIED;
+const ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_MAX = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_BLOCKED;
+
+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,
+  };
+
+  using FieldMetadata_BeginMainFrameQueueCriticalEstimateDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CompositorTimingHistory>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BeginMainFrameQueueCriticalEstimateDeltaUs kBeginMainFrameQueueCriticalEstimateDeltaUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BeginMainFrameQueueNotCriticalEstimateDeltaUs kBeginMainFrameQueueNotCriticalEstimateDeltaUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BeginMainFrameStartToReadyToCommitEstimateDeltaUs kBeginMainFrameStartToReadyToCommitEstimateDeltaUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CommitToReadyToActivateEstimateDeltaUs kCommitToReadyToActivateEstimateDeltaUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PrepareTilesEstimateDeltaUs kPrepareTilesEstimateDeltaUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ActivateEstimateDeltaUs kActivateEstimateDeltaUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DrawEstimateDeltaUs kDrawEstimateDeltaUs() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_SourceId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BeginFrameSourceState>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SourceId kSourceId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Paused kPaused() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NumObservers kNumObservers() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LastBeginFrameArgs kLastBeginFrameArgs() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_DroppedBeginFrameArgs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginFrameObserverState>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DroppedBeginFrameArgs kDroppedBeginFrameArgs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LastBeginFrameArgs kLastBeginFrameArgs() { return {}; }
+  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,
+  };
+  using TimestampsInUs = ::perfetto::protos::pbzero::BeginImplFrameArgs_TimestampsInUs;
+  using State = ::perfetto::protos::pbzero::BeginImplFrameArgs_State;
+  static const State BEGIN_FRAME_FINISHED = BeginImplFrameArgs_State_BEGIN_FRAME_FINISHED;
+  static const State BEGIN_FRAME_USING = BeginImplFrameArgs_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UpdatedAtUs kUpdatedAtUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FinishedAtUs kFinishedAtUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_State kState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CurrentArgs kCurrentArgs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LastArgs kLastArgs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TimestampsInUs kTimestampsInUs() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_IntervalDelta =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginImplFrameArgs_TimestampsInUs>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IntervalDelta kIntervalDelta() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NowToDeadlineDelta kNowToDeadlineDelta() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FrameTimeToNowDelta kFrameTimeToNowDelta() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FrameTimeToDeadlineDelta kFrameTimeToDeadlineDelta() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Now kNow() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FrameTime kFrameTime() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Deadline kDeadline() { return {}; }
+  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,
+  };
+  using BeginFrameArgsType = ::perfetto::protos::pbzero::BeginFrameArgs_BeginFrameArgsType;
+  static const BeginFrameArgsType BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED;
+  static const BeginFrameArgsType BEGIN_FRAME_ARGS_TYPE_INVALID = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_INVALID;
+  static const BeginFrameArgsType BEGIN_FRAME_ARGS_TYPE_NORMAL = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_NORMAL;
+  static const BeginFrameArgsType BEGIN_FRAME_ARGS_TYPE_MISSED = BeginFrameArgs_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SourceId kSourceId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SequenceNumber kSequenceNumber() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FrameTimeUs kFrameTimeUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DeadlineUs kDeadlineUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IntervalDeltaUs kIntervalDeltaUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OnCriticalPath kOnCriticalPath() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AnimateOnly kAnimateOnly() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SourceLocationIid kSourceLocationIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SourceLocation kSourceLocation() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FramesThrottledSinceLast kFramesThrottledSinceLast() { return {}; }
+  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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MajorState kMajorState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MinorState kMinorState() { return {}; }
+  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,
+  };
+  using TreePriority = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_TreePriority;
+  using ScrollHandlerState = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_ScrollHandlerState;
+  static const TreePriority TREE_PRIORITY_UNSPECIFIED = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_UNSPECIFIED;
+  static const TreePriority TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES;
+  static const TreePriority TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY;
+  static const TreePriority TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY;
+  static const ScrollHandlerState SCROLL_HANDLER_UNSPECIFIED = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_HANDLER_UNSPECIFIED;
+  static const ScrollHandlerState SCROLL_AFFECTS_SCROLL_HANDLER = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_AFFECTS_SCROLL_HANDLER;
+  static const ScrollHandlerState SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER = ChromeCompositorStateMachine_MinorState_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CommitCount kCommitCount() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CurrentFrameNumber kCurrentFrameNumber() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LastFrameNumberSubmitPerformed kLastFrameNumberSubmitPerformed() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LastFrameNumberDrawPerformed kLastFrameNumberDrawPerformed() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LastFrameNumberBeginMainFrameSent kLastFrameNumberBeginMainFrameSent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DidDraw kDidDraw() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DidSendBeginMainFrameForCurrentFrame kDidSendBeginMainFrameForCurrentFrame() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DidNotifyBeginMainFrameNotExpectedUntil kDidNotifyBeginMainFrameNotExpectedUntil() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DidNotifyBeginMainFrameNotExpectedSoon kDidNotifyBeginMainFrameNotExpectedSoon() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WantsBeginMainFrameNotExpected kWantsBeginMainFrameNotExpected() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DidCommitDuringFrame kDidCommitDuringFrame() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DidInvalidateLayerTreeFrameSink kDidInvalidateLayerTreeFrameSink() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DidPerformImplSideInvalidaion kDidPerformImplSideInvalidaion() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DidPrepareTiles kDidPrepareTiles() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ConsecutiveCheckerboardAnimations kConsecutiveCheckerboardAnimations() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PendingSubmitFrames kPendingSubmitFrames() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SubmitFramesWithCurrentLayerTreeFrameSink kSubmitFramesWithCurrentLayerTreeFrameSink() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NeedsRedraw kNeedsRedraw() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NeedsPrepareTiles kNeedsPrepareTiles() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NeedsBeginMainFrame kNeedsBeginMainFrame() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NeedsOneBeginImplFrame kNeedsOneBeginImplFrame() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Visible kVisible() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BeginFrameSourcePaused kBeginFrameSourcePaused() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CanDraw kCanDraw() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ResourcelessDraw kResourcelessDraw() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HasPendingTree kHasPendingTree() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PendingTreeIsReadyForActivation kPendingTreeIsReadyForActivation() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ActiveTreeNeedsFirstDraw kActiveTreeNeedsFirstDraw() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ActiveTreeIsReadyToDraw kActiveTreeIsReadyToDraw() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DidCreateAndInitializeFirstLayerTreeFrameSink kDidCreateAndInitializeFirstLayerTreeFrameSink() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TreePriority kTreePriority() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ScrollHandlerState kScrollHandlerState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CriticalBeginMainFrameToActivateIsFast kCriticalBeginMainFrameToActivateIsFast() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MainThreadMissedLastDeadline kMainThreadMissedLastDeadline() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VideoNeedsBeginFrames kVideoNeedsBeginFrames() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DeferBeginMainFrame kDeferBeginMainFrame() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LastCommitHadNoUpdates kLastCommitHadNoUpdates() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DidDrawInLastFrame kDidDrawInLastFrame() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DidSubmitInLastFrame kDidSubmitInLastFrame() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NeedsImplSideInvalidation kNeedsImplSideInvalidation() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CurrentPendingTreeIsImplSide kCurrentPendingTreeIsImplSide() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PreviousPendingTreeWasImplSide kPreviousPendingTreeWasImplSide() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessingAnimationWorkletsForActiveTree kProcessingAnimationWorkletsForActiveTree() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessingAnimationWorkletsForPendingTree kProcessingAnimationWorkletsForPendingTree() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessingPaintWorkletsForPendingTree kProcessingPaintWorkletsForPendingTree() { return {}; }
+  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,
+  };
+  using BeginImplFrameState = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginImplFrameState;
+  using BeginMainFrameState = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginMainFrameState;
+  using LayerTreeFrameSinkState = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState;
+  using ForcedRedrawOnTimeoutState = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState;
+  static const BeginImplFrameState BEGIN_IMPL_FRAME_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_UNSPECIFIED;
+  static const BeginImplFrameState BEGIN_IMPL_FRAME_IDLE = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_IDLE;
+  static const BeginImplFrameState BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME;
+  static const BeginImplFrameState BEGIN_IMPL_FRAME_INSIDE_DEADLINE = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_DEADLINE;
+  static const BeginMainFrameState BEGIN_MAIN_FRAME_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_UNSPECIFIED;
+  static const BeginMainFrameState BEGIN_MAIN_FRAME_IDLE = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_IDLE;
+  static const BeginMainFrameState BEGIN_MAIN_FRAME_SENT = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_SENT;
+  static const BeginMainFrameState BEGIN_MAIN_FRAME_READY_TO_COMMIT = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_READY_TO_COMMIT;
+  static const LayerTreeFrameSinkState LAYER_TREE_FRAME_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_UNSPECIFIED;
+  static const LayerTreeFrameSinkState LAYER_TREE_FRAME_NONE = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_NONE;
+  static const LayerTreeFrameSinkState LAYER_TREE_FRAME_ACTIVE = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_ACTIVE;
+  static const LayerTreeFrameSinkState LAYER_TREE_FRAME_CREATING = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_CREATING;
+  static const LayerTreeFrameSinkState LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT;
+  static const LayerTreeFrameSinkState LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION;
+  static const ForcedRedrawOnTimeoutState FORCED_REDRAW_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_UNSPECIFIED;
+  static const ForcedRedrawOnTimeoutState FORCED_REDRAW_IDLE = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_IDLE;
+  static const ForcedRedrawOnTimeoutState FORCED_REDRAW_WAITING_FOR_COMMIT = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_COMMIT;
+  static const ForcedRedrawOnTimeoutState FORCED_REDRAW_WAITING_FOR_ACTIVATION = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_ACTIVATION;
+  static const ForcedRedrawOnTimeoutState FORCED_REDRAW_WAITING_FOR_DRAW = ChromeCompositorStateMachine_MajorState_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NextAction kNextAction() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BeginImplFrameState kBeginImplFrameState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BeginMainFrameState kBeginMainFrameState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LayerTreeFrameSinkState kLayerTreeFrameSinkState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ForcedRedrawState kForcedRedrawState() { return {}; }
+  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,
+  };
+  using BeginImplFrameDeadlineMode = ::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode;
+  static const BeginImplFrameDeadlineMode DEADLINE_MODE_UNSPECIFIED = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_UNSPECIFIED;
+  static const BeginImplFrameDeadlineMode DEADLINE_MODE_NONE = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_NONE;
+  static const BeginImplFrameDeadlineMode DEADLINE_MODE_IMMEDIATE = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_IMMEDIATE;
+  static const BeginImplFrameDeadlineMode DEADLINE_MODE_REGULAR = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_REGULAR;
+  static const BeginImplFrameDeadlineMode DEADLINE_MODE_LATE = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_LATE;
+  static const BeginImplFrameDeadlineMode DEADLINE_MODE_BLOCKED = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_BLOCKED;
+
+  using FieldMetadata_StateMachine =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeCompositorStateMachine,
+      ChromeCompositorSchedulerState>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StateMachine kStateMachine() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ObservingBeginFrameSource kObservingBeginFrameSource() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BeginImplFrameDeadlineTask kBeginImplFrameDeadlineTask() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PendingBeginFrameTask kPendingBeginFrameTask() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SkippedLastFrameMissedExceededDeadline kSkippedLastFrameMissedExceededDeadline() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InsideAction kInsideAction() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DeadlineMode kDeadlineMode() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DeadlineUs kDeadlineUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DeadlineScheduledAtUs kDeadlineScheduledAtUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NowUs kNowUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NowToDeadlineDeltaUs kNowToDeadlineDeltaUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NowToDeadlineScheduledAtDeltaUs kNowToDeadlineScheduledAtDeltaUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BeginImplFrameArgs kBeginImplFrameArgs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BeginFrameObserverState kBeginFrameObserverState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BeginFrameSourceState kBeginFrameSourceState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CompositorTimingHistory kCompositorTimingHistory() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_NumberOfExceptions =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeContentSettingsEventInfo>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NumberOfExceptions kNumberOfExceptions() { return {}; }
+  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 {
+
+enum ChromeFrameReporter_FrameDropReason : int32_t;
+enum ChromeFrameReporter_ScrollState : int32_t;
+enum ChromeFrameReporter_State : int32_t;
+
+enum ChromeFrameReporter_State : int32_t {
+  ChromeFrameReporter_State_STATE_NO_UPDATE_DESIRED = 0,
+  ChromeFrameReporter_State_STATE_PRESENTED_ALL = 1,
+  ChromeFrameReporter_State_STATE_PRESENTED_PARTIAL = 2,
+  ChromeFrameReporter_State_STATE_DROPPED = 3,
+};
+
+const ChromeFrameReporter_State ChromeFrameReporter_State_MIN = ChromeFrameReporter_State_STATE_NO_UPDATE_DESIRED;
+const ChromeFrameReporter_State ChromeFrameReporter_State_MAX = ChromeFrameReporter_State_STATE_DROPPED;
+
+enum ChromeFrameReporter_FrameDropReason : int32_t {
+  ChromeFrameReporter_FrameDropReason_REASON_UNSPECIFIED = 0,
+  ChromeFrameReporter_FrameDropReason_REASON_DISPLAY_COMPOSITOR = 1,
+  ChromeFrameReporter_FrameDropReason_REASON_MAIN_THREAD = 2,
+  ChromeFrameReporter_FrameDropReason_REASON_CLIENT_COMPOSITOR = 3,
+};
+
+const ChromeFrameReporter_FrameDropReason ChromeFrameReporter_FrameDropReason_MIN = ChromeFrameReporter_FrameDropReason_REASON_UNSPECIFIED;
+const ChromeFrameReporter_FrameDropReason ChromeFrameReporter_FrameDropReason_MAX = ChromeFrameReporter_FrameDropReason_REASON_CLIENT_COMPOSITOR;
+
+enum ChromeFrameReporter_ScrollState : int32_t {
+  ChromeFrameReporter_ScrollState_SCROLL_NONE = 0,
+  ChromeFrameReporter_ScrollState_SCROLL_MAIN_THREAD = 1,
+  ChromeFrameReporter_ScrollState_SCROLL_COMPOSITOR_THREAD = 2,
+  ChromeFrameReporter_ScrollState_SCROLL_UNKNOWN = 3,
+};
+
+const ChromeFrameReporter_ScrollState ChromeFrameReporter_ScrollState_MIN = ChromeFrameReporter_ScrollState_SCROLL_NONE;
+const ChromeFrameReporter_ScrollState ChromeFrameReporter_ScrollState_MAX = ChromeFrameReporter_ScrollState_SCROLL_UNKNOWN;
+
+class ChromeFrameReporter_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ 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(); }
+};
+
+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,
+  };
+  using State = ::perfetto::protos::pbzero::ChromeFrameReporter_State;
+  using FrameDropReason = ::perfetto::protos::pbzero::ChromeFrameReporter_FrameDropReason;
+  using ScrollState = ::perfetto::protos::pbzero::ChromeFrameReporter_ScrollState;
+  static const State STATE_NO_UPDATE_DESIRED = ChromeFrameReporter_State_STATE_NO_UPDATE_DESIRED;
+  static const State STATE_PRESENTED_ALL = ChromeFrameReporter_State_STATE_PRESENTED_ALL;
+  static const State STATE_PRESENTED_PARTIAL = ChromeFrameReporter_State_STATE_PRESENTED_PARTIAL;
+  static const State STATE_DROPPED = ChromeFrameReporter_State_STATE_DROPPED;
+  static const FrameDropReason REASON_UNSPECIFIED = ChromeFrameReporter_FrameDropReason_REASON_UNSPECIFIED;
+  static const FrameDropReason REASON_DISPLAY_COMPOSITOR = ChromeFrameReporter_FrameDropReason_REASON_DISPLAY_COMPOSITOR;
+  static const FrameDropReason REASON_MAIN_THREAD = ChromeFrameReporter_FrameDropReason_REASON_MAIN_THREAD;
+  static const FrameDropReason REASON_CLIENT_COMPOSITOR = ChromeFrameReporter_FrameDropReason_REASON_CLIENT_COMPOSITOR;
+  static const ScrollState SCROLL_NONE = ChromeFrameReporter_ScrollState_SCROLL_NONE;
+  static const ScrollState SCROLL_MAIN_THREAD = ChromeFrameReporter_ScrollState_SCROLL_MAIN_THREAD;
+  static const ScrollState SCROLL_COMPOSITOR_THREAD = ChromeFrameReporter_ScrollState_SCROLL_COMPOSITOR_THREAD;
+  static const ScrollState SCROLL_UNKNOWN = ChromeFrameReporter_ScrollState_SCROLL_UNKNOWN;
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeFrameReporter_State,
+      ChromeFrameReporter>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_State kState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Reason kReason() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FrameSource kFrameSource() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FrameSequence kFrameSequence() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AffectsSmoothness kAffectsSmoothness() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ScrollState kScrollState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HasMainAnimation kHasMainAnimation() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HasCompositorAnimation kHasCompositorAnimation() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HasSmoothInputMain kHasSmoothInputMain() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HasMissingContent kHasMissingContent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LayerTreeHostId kLayerTreeHostId() { return {}; }
+  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);
+  }
+};
+
+} // 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,
+  };
+
+  using FieldMetadata_NameHash =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeHistogramSample>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NameHash kNameHash() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Sample kSample() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NameIid kNameIid() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HistogramName>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Iid kIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeKeyedService>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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;
+enum ChromeLatencyInfo_LatencyComponentType : int32_t;
+enum ChromeLatencyInfo_Step : int32_t;
+
+enum ChromeLatencyInfo_Step : int32_t {
+  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,
+};
+
+const ChromeLatencyInfo_Step ChromeLatencyInfo_Step_MIN = ChromeLatencyInfo_Step_STEP_UNSPECIFIED;
+const ChromeLatencyInfo_Step ChromeLatencyInfo_Step_MAX = ChromeLatencyInfo_Step_STEP_FINISHED_SWAP_BUFFERS;
+
+enum ChromeLatencyInfo_LatencyComponentType : int32_t {
+  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,
+};
+
+const ChromeLatencyInfo_LatencyComponentType ChromeLatencyInfo_LatencyComponentType_MIN = ChromeLatencyInfo_LatencyComponentType_COMPONENT_UNSPECIFIED;
+const ChromeLatencyInfo_LatencyComponentType ChromeLatencyInfo_LatencyComponentType_MAX = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP;
+
+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,
+  };
+  using ComponentInfo = ::perfetto::protos::pbzero::ChromeLatencyInfo_ComponentInfo;
+  using Step = ::perfetto::protos::pbzero::ChromeLatencyInfo_Step;
+  using LatencyComponentType = ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType;
+  static const Step STEP_UNSPECIFIED = ChromeLatencyInfo_Step_STEP_UNSPECIFIED;
+  static const Step STEP_SEND_INPUT_EVENT_UI = ChromeLatencyInfo_Step_STEP_SEND_INPUT_EVENT_UI;
+  static const Step STEP_HANDLE_INPUT_EVENT_IMPL = ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_IMPL;
+  static const Step STEP_DID_HANDLE_INPUT_AND_OVERSCROLL = ChromeLatencyInfo_Step_STEP_DID_HANDLE_INPUT_AND_OVERSCROLL;
+  static const Step STEP_HANDLE_INPUT_EVENT_MAIN = ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN;
+  static const Step STEP_MAIN_THREAD_SCROLL_UPDATE = ChromeLatencyInfo_Step_STEP_MAIN_THREAD_SCROLL_UPDATE;
+  static const Step STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT = ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT;
+  static const Step STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL = ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL;
+  static const Step STEP_HANDLED_INPUT_EVENT_IMPL = ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_IMPL;
+  static const Step STEP_SWAP_BUFFERS = ChromeLatencyInfo_Step_STEP_SWAP_BUFFERS;
+  static const Step STEP_DRAW_AND_SWAP = ChromeLatencyInfo_Step_STEP_DRAW_AND_SWAP;
+  static const Step STEP_FINISHED_SWAP_BUFFERS = ChromeLatencyInfo_Step_STEP_FINISHED_SWAP_BUFFERS;
+  static const LatencyComponentType COMPONENT_UNSPECIFIED = ChromeLatencyInfo_LatencyComponentType_COMPONENT_UNSPECIFIED;
+  static const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH;
+  static const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL;
+  static const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL;
+  static const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL;
+  static const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_UI = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_UI;
+  static const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN;
+  static const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN;
+  static const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL;
+  static const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT;
+  static const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH;
+  static const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP;
+  static const LatencyComponentType COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME = ChromeLatencyInfo_LatencyComponentType_COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME;
+  static const LatencyComponentType COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER;
+  static const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP = ChromeLatencyInfo_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceId kTraceId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Step kStep() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FrameTreeNodeId kFrameTreeNodeId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ComponentInfo kComponentInfo() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IsCoalesced kIsCoalesced() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GestureScrollId kGestureScrollId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TouchId kTouchId() { return {}; }
+  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,
+  };
+
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ComponentType kComponentType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TimeUs kTimeUs() { return {}; }
+  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 {
+
+enum ChromeLegacyIpc_MessageClass : int32_t;
+
+enum ChromeLegacyIpc_MessageClass : int32_t {
+  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,
+};
+
+const ChromeLegacyIpc_MessageClass ChromeLegacyIpc_MessageClass_MIN = ChromeLegacyIpc_MessageClass_CLASS_UNSPECIFIED;
+const ChromeLegacyIpc_MessageClass ChromeLegacyIpc_MessageClass_MAX = ChromeLegacyIpc_MessageClass_CLASS_UNFREEZABLE_FRAME;
+
+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,
+  };
+  using MessageClass = ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass;
+  static const MessageClass CLASS_UNSPECIFIED = ChromeLegacyIpc_MessageClass_CLASS_UNSPECIFIED;
+  static const MessageClass CLASS_AUTOMATION = ChromeLegacyIpc_MessageClass_CLASS_AUTOMATION;
+  static const MessageClass CLASS_FRAME = ChromeLegacyIpc_MessageClass_CLASS_FRAME;
+  static const MessageClass CLASS_PAGE = ChromeLegacyIpc_MessageClass_CLASS_PAGE;
+  static const MessageClass CLASS_VIEW = ChromeLegacyIpc_MessageClass_CLASS_VIEW;
+  static const MessageClass CLASS_WIDGET = ChromeLegacyIpc_MessageClass_CLASS_WIDGET;
+  static const MessageClass CLASS_INPUT = ChromeLegacyIpc_MessageClass_CLASS_INPUT;
+  static const MessageClass CLASS_TEST = ChromeLegacyIpc_MessageClass_CLASS_TEST;
+  static const MessageClass CLASS_WORKER = ChromeLegacyIpc_MessageClass_CLASS_WORKER;
+  static const MessageClass CLASS_NACL = ChromeLegacyIpc_MessageClass_CLASS_NACL;
+  static const MessageClass CLASS_GPU_CHANNEL = ChromeLegacyIpc_MessageClass_CLASS_GPU_CHANNEL;
+  static const MessageClass CLASS_MEDIA = ChromeLegacyIpc_MessageClass_CLASS_MEDIA;
+  static const MessageClass CLASS_PPAPI = ChromeLegacyIpc_MessageClass_CLASS_PPAPI;
+  static const MessageClass CLASS_CHROME = ChromeLegacyIpc_MessageClass_CLASS_CHROME;
+  static const MessageClass CLASS_DRAG = ChromeLegacyIpc_MessageClass_CLASS_DRAG;
+  static const MessageClass CLASS_PRINT = ChromeLegacyIpc_MessageClass_CLASS_PRINT;
+  static const MessageClass CLASS_EXTENSION = ChromeLegacyIpc_MessageClass_CLASS_EXTENSION;
+  static const MessageClass CLASS_TEXT_INPUT_CLIENT = ChromeLegacyIpc_MessageClass_CLASS_TEXT_INPUT_CLIENT;
+  static const MessageClass CLASS_BLINK_TEST = ChromeLegacyIpc_MessageClass_CLASS_BLINK_TEST;
+  static const MessageClass CLASS_ACCESSIBILITY = ChromeLegacyIpc_MessageClass_CLASS_ACCESSIBILITY;
+  static const MessageClass CLASS_PRERENDER = ChromeLegacyIpc_MessageClass_CLASS_PRERENDER;
+  static const MessageClass CLASS_CHROMOTING = ChromeLegacyIpc_MessageClass_CLASS_CHROMOTING;
+  static const MessageClass CLASS_BROWSER_PLUGIN = ChromeLegacyIpc_MessageClass_CLASS_BROWSER_PLUGIN;
+  static const MessageClass CLASS_ANDROID_WEB_VIEW = ChromeLegacyIpc_MessageClass_CLASS_ANDROID_WEB_VIEW;
+  static const MessageClass CLASS_NACL_HOST = ChromeLegacyIpc_MessageClass_CLASS_NACL_HOST;
+  static const MessageClass CLASS_ENCRYPTED_MEDIA = ChromeLegacyIpc_MessageClass_CLASS_ENCRYPTED_MEDIA;
+  static const MessageClass CLASS_CAST = ChromeLegacyIpc_MessageClass_CLASS_CAST;
+  static const MessageClass CLASS_GIN_JAVA_BRIDGE = ChromeLegacyIpc_MessageClass_CLASS_GIN_JAVA_BRIDGE;
+  static const MessageClass CLASS_CHROME_UTILITY_PRINTING = ChromeLegacyIpc_MessageClass_CLASS_CHROME_UTILITY_PRINTING;
+  static const MessageClass CLASS_OZONE_GPU = ChromeLegacyIpc_MessageClass_CLASS_OZONE_GPU;
+  static const MessageClass CLASS_WEB_TEST = ChromeLegacyIpc_MessageClass_CLASS_WEB_TEST;
+  static const MessageClass CLASS_NETWORK_HINTS = ChromeLegacyIpc_MessageClass_CLASS_NETWORK_HINTS;
+  static const MessageClass CLASS_EXTENSIONS_GUEST_VIEW = ChromeLegacyIpc_MessageClass_CLASS_EXTENSIONS_GUEST_VIEW;
+  static const MessageClass CLASS_GUEST_VIEW = ChromeLegacyIpc_MessageClass_CLASS_GUEST_VIEW;
+  static const MessageClass CLASS_MEDIA_PLAYER_DELEGATE = ChromeLegacyIpc_MessageClass_CLASS_MEDIA_PLAYER_DELEGATE;
+  static const MessageClass CLASS_EXTENSION_WORKER = ChromeLegacyIpc_MessageClass_CLASS_EXTENSION_WORKER;
+  static const MessageClass CLASS_SUBRESOURCE_FILTER = ChromeLegacyIpc_MessageClass_CLASS_SUBRESOURCE_FILTER;
+  static const MessageClass CLASS_UNFREEZABLE_FRAME = ChromeLegacyIpc_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MessageClass kMessageClass() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MessageLine kMessageLine() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_SentMessagesInQueue =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeMessagePump>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SentMessagesInQueue kSentMessagesInQueue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IoHandlerLocationIid kIoHandlerLocationIid() { return {}; }
+  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=*/3, /*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(); }
+};
+
+class ChromeMojoEventInfo : public ::protozero::Message {
+ public:
+  using Decoder = ChromeMojoEventInfo_Decoder;
+  enum : int32_t {
+    kWatcherNotifyInterfaceTagFieldNumber = 1,
+    kIpcHashFieldNumber = 2,
+    kMojoInterfaceTagFieldNumber = 3,
+  };
+
+  using FieldMetadata_WatcherNotifyInterfaceTag =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeMojoEventInfo>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_WatcherNotifyInterfaceTag kWatcherNotifyInterfaceTag() { return {}; }
+  void set_watcher_notify_interface_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_WatcherNotifyInterfaceTag::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IpcHash kIpcHash() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MojoInterfaceTag kMojoInterfaceTag() { return {}; }
+  void set_mojo_interface_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_MojoInterfaceTag::kFieldId, data, 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);
+  }
+};
+
+} // 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 {
+
+enum ChromeProcessDescriptor_ProcessType : int32_t;
+
+enum ChromeProcessDescriptor_ProcessType : int32_t {
+  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,
+};
+
+const ChromeProcessDescriptor_ProcessType ChromeProcessDescriptor_ProcessType_MIN = ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED;
+const ChromeProcessDescriptor_ProcessType ChromeProcessDescriptor_ProcessType_MAX = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHAPEDETECTION;
+
+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,
+  };
+  using ProcessType = ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType;
+  static const ProcessType PROCESS_UNSPECIFIED = ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED;
+  static const ProcessType PROCESS_BROWSER = ChromeProcessDescriptor_ProcessType_PROCESS_BROWSER;
+  static const ProcessType PROCESS_RENDERER = ChromeProcessDescriptor_ProcessType_PROCESS_RENDERER;
+  static const ProcessType PROCESS_UTILITY = ChromeProcessDescriptor_ProcessType_PROCESS_UTILITY;
+  static const ProcessType PROCESS_ZYGOTE = ChromeProcessDescriptor_ProcessType_PROCESS_ZYGOTE;
+  static const ProcessType PROCESS_SANDBOX_HELPER = ChromeProcessDescriptor_ProcessType_PROCESS_SANDBOX_HELPER;
+  static const ProcessType PROCESS_GPU = ChromeProcessDescriptor_ProcessType_PROCESS_GPU;
+  static const ProcessType PROCESS_PPAPI_PLUGIN = ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_PLUGIN;
+  static const ProcessType PROCESS_PPAPI_BROKER = ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_BROKER;
+  static const ProcessType PROCESS_SERVICE_NETWORK = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_NETWORK;
+  static const ProcessType PROCESS_SERVICE_TRACING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_TRACING;
+  static const ProcessType PROCESS_SERVICE_STORAGE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_STORAGE;
+  static const ProcessType PROCESS_SERVICE_AUDIO = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_AUDIO;
+  static const ProcessType PROCESS_SERVICE_DATA_DECODER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_DATA_DECODER;
+  static const ProcessType PROCESS_SERVICE_UTIL_WIN = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_UTIL_WIN;
+  static const ProcessType PROCESS_SERVICE_PROXY_RESOLVER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PROXY_RESOLVER;
+  static const ProcessType PROCESS_SERVICE_CDM = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CDM;
+  static const ProcessType PROCESS_SERVICE_VIDEO_CAPTURE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_VIDEO_CAPTURE;
+  static const ProcessType PROCESS_SERVICE_UNZIPPER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_UNZIPPER;
+  static const ProcessType PROCESS_SERVICE_MIRRORING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MIRRORING;
+  static const ProcessType PROCESS_SERVICE_FILEPATCHER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_FILEPATCHER;
+  static const ProcessType PROCESS_SERVICE_TTS = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_TTS;
+  static const ProcessType PROCESS_SERVICE_PRINTING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PRINTING;
+  static const ProcessType PROCESS_SERVICE_QUARANTINE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_QUARANTINE;
+  static const ProcessType PROCESS_SERVICE_CROS_LOCALSEARCH = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CROS_LOCALSEARCH;
+  static const ProcessType PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER;
+  static const ProcessType PROCESS_SERVICE_FILEUTIL = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_FILEUTIL;
+  static const ProcessType PROCESS_SERVICE_PRINTCOMPOSITOR = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PRINTCOMPOSITOR;
+  static const ProcessType PROCESS_SERVICE_PAINTPREVIEW = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PAINTPREVIEW;
+  static const ProcessType PROCESS_SERVICE_SPEECHRECOGNITION = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SPEECHRECOGNITION;
+  static const ProcessType PROCESS_SERVICE_XRDEVICE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_XRDEVICE;
+  static const ProcessType PROCESS_SERVICE_READICON = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_READICON;
+  static const ProcessType PROCESS_SERVICE_LANGUAGEDETECTION = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_LANGUAGEDETECTION;
+  static const ProcessType PROCESS_SERVICE_SHARING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHARING;
+  static const ProcessType PROCESS_SERVICE_MEDIAPARSER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MEDIAPARSER;
+  static const ProcessType PROCESS_SERVICE_QRCODEGENERATOR = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_QRCODEGENERATOR;
+  static const ProcessType PROCESS_SERVICE_PROFILEIMPORT = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PROFILEIMPORT;
+  static const ProcessType PROCESS_SERVICE_IME = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_IME;
+  static const ProcessType PROCESS_SERVICE_RECORDING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_RECORDING;
+  static const ProcessType PROCESS_SERVICE_SHAPEDETECTION = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHAPEDETECTION;
+
+  using FieldMetadata_ProcessType =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType,
+      ChromeProcessDescriptor>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessType kProcessType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessPriority kProcessPriority() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LegacySortIndex kLegacySortIndex() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HostAppPackageName kHostAppPackageName() { return {}; }
+  void set_host_app_package_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HostAppPackageName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CrashTraceId kCrashTraceId() { return {}; }
+  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,
+};
+
+const ChromeRAILMode ChromeRAILMode_MIN = RAIL_MODE_NONE;
+const ChromeRAILMode ChromeRAILMode_MAX = RAIL_MODE_LOAD;
+
+class ChromeRendererSchedulerState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*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(); }
+};
+
+class ChromeRendererSchedulerState : public ::protozero::Message {
+ public:
+  using Decoder = ChromeRendererSchedulerState_Decoder;
+  enum : int32_t {
+    kRailModeFieldNumber = 1,
+  };
+
+  using FieldMetadata_RailMode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeRAILMode,
+      ChromeRendererSchedulerState>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RailMode kRailMode() { return {}; }
+  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);
+  }
+};
+
+} // 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 {
+
+enum ChromeThreadDescriptor_ThreadType : int32_t;
+
+enum ChromeThreadDescriptor_ThreadType : int32_t {
+  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_MEMORY_INFRA = 50,
+  ChromeThreadDescriptor_ThreadType_THREAD_SAMPLING_PROFILER = 51,
+};
+
+const ChromeThreadDescriptor_ThreadType ChromeThreadDescriptor_ThreadType_MIN = ChromeThreadDescriptor_ThreadType_THREAD_UNSPECIFIED;
+const ChromeThreadDescriptor_ThreadType ChromeThreadDescriptor_ThreadType_MAX = ChromeThreadDescriptor_ThreadType_THREAD_SAMPLING_PROFILER;
+
+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,
+  };
+  using ThreadType = ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType;
+  static const ThreadType THREAD_UNSPECIFIED = ChromeThreadDescriptor_ThreadType_THREAD_UNSPECIFIED;
+  static const ThreadType THREAD_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_MAIN;
+  static const ThreadType THREAD_IO = ChromeThreadDescriptor_ThreadType_THREAD_IO;
+  static const ThreadType THREAD_POOL_BG_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_WORKER;
+  static const ThreadType THREAD_POOL_FG_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_WORKER;
+  static const ThreadType THREAD_POOL_FG_BLOCKING = ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_BLOCKING;
+  static const ThreadType THREAD_POOL_BG_BLOCKING = ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_BLOCKING;
+  static const ThreadType THREAD_POOL_SERVICE = ChromeThreadDescriptor_ThreadType_THREAD_POOL_SERVICE;
+  static const ThreadType THREAD_COMPOSITOR = ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR;
+  static const ThreadType THREAD_VIZ_COMPOSITOR = ChromeThreadDescriptor_ThreadType_THREAD_VIZ_COMPOSITOR;
+  static const ThreadType THREAD_COMPOSITOR_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR_WORKER;
+  static const ThreadType THREAD_SERVICE_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_SERVICE_WORKER;
+  static const ThreadType THREAD_NETWORK_SERVICE = ChromeThreadDescriptor_ThreadType_THREAD_NETWORK_SERVICE;
+  static const ThreadType THREAD_CHILD_IO = ChromeThreadDescriptor_ThreadType_THREAD_CHILD_IO;
+  static const ThreadType THREAD_BROWSER_IO = ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_IO;
+  static const ThreadType THREAD_BROWSER_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_MAIN;
+  static const ThreadType THREAD_RENDERER_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_RENDERER_MAIN;
+  static const ThreadType THREAD_UTILITY_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_UTILITY_MAIN;
+  static const ThreadType THREAD_GPU_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_GPU_MAIN;
+  static const ThreadType THREAD_CACHE_BLOCKFILE = ChromeThreadDescriptor_ThreadType_THREAD_CACHE_BLOCKFILE;
+  static const ThreadType THREAD_MEDIA = ChromeThreadDescriptor_ThreadType_THREAD_MEDIA;
+  static const ThreadType THREAD_AUDIO_OUTPUTDEVICE = ChromeThreadDescriptor_ThreadType_THREAD_AUDIO_OUTPUTDEVICE;
+  static const ThreadType THREAD_AUDIO_INPUTDEVICE = ChromeThreadDescriptor_ThreadType_THREAD_AUDIO_INPUTDEVICE;
+  static const ThreadType THREAD_GPU_MEMORY = ChromeThreadDescriptor_ThreadType_THREAD_GPU_MEMORY;
+  static const ThreadType THREAD_GPU_VSYNC = ChromeThreadDescriptor_ThreadType_THREAD_GPU_VSYNC;
+  static const ThreadType THREAD_DXA_VIDEODECODER = ChromeThreadDescriptor_ThreadType_THREAD_DXA_VIDEODECODER;
+  static const ThreadType THREAD_BROWSER_WATCHDOG = ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_WATCHDOG;
+  static const ThreadType THREAD_WEBRTC_NETWORK = ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_NETWORK;
+  static const ThreadType THREAD_WINDOW_OWNER = ChromeThreadDescriptor_ThreadType_THREAD_WINDOW_OWNER;
+  static const ThreadType THREAD_WEBRTC_SIGNALING = ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_SIGNALING;
+  static const ThreadType THREAD_WEBRTC_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_WORKER;
+  static const ThreadType THREAD_PPAPI_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_PPAPI_MAIN;
+  static const ThreadType THREAD_GPU_WATCHDOG = ChromeThreadDescriptor_ThreadType_THREAD_GPU_WATCHDOG;
+  static const ThreadType THREAD_SWAPPER = ChromeThreadDescriptor_ThreadType_THREAD_SWAPPER;
+  static const ThreadType THREAD_GAMEPAD_POLLING = ChromeThreadDescriptor_ThreadType_THREAD_GAMEPAD_POLLING;
+  static const ThreadType THREAD_WEBCRYPTO = ChromeThreadDescriptor_ThreadType_THREAD_WEBCRYPTO;
+  static const ThreadType THREAD_DATABASE = ChromeThreadDescriptor_ThreadType_THREAD_DATABASE;
+  static const ThreadType THREAD_PROXYRESOLVER = ChromeThreadDescriptor_ThreadType_THREAD_PROXYRESOLVER;
+  static const ThreadType THREAD_DEVTOOLSADB = ChromeThreadDescriptor_ThreadType_THREAD_DEVTOOLSADB;
+  static const ThreadType THREAD_NETWORKCONFIGWATCHER = ChromeThreadDescriptor_ThreadType_THREAD_NETWORKCONFIGWATCHER;
+  static const ThreadType THREAD_WASAPI_RENDER = ChromeThreadDescriptor_ThreadType_THREAD_WASAPI_RENDER;
+  static const ThreadType THREAD_MEMORY_INFRA = ChromeThreadDescriptor_ThreadType_THREAD_MEMORY_INFRA;
+  static const ThreadType THREAD_SAMPLING_PROFILER = ChromeThreadDescriptor_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadType kThreadType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LegacySortIndex kLegacySortIndex() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Action =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeUserEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Action kAction() { return {}; }
+  void set_action(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Action::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ActionHash kActionHash() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Dpi =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeWindowHandleEventInfo>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Dpi kDpi() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MessageId kMessageId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HwndPtr kHwndPtr() { return {}; }
+  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/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 {
+
+enum CounterDescriptor_BuiltinCounterType : int32_t;
+enum CounterDescriptor_Unit : int32_t;
+
+enum CounterDescriptor_BuiltinCounterType : int32_t {
+  CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED = 0,
+  CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_TIME_NS = 1,
+  CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT = 2,
+};
+
+const CounterDescriptor_BuiltinCounterType CounterDescriptor_BuiltinCounterType_MIN = CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED;
+const CounterDescriptor_BuiltinCounterType CounterDescriptor_BuiltinCounterType_MAX = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT;
+
+enum CounterDescriptor_Unit : int32_t {
+  CounterDescriptor_Unit_UNIT_UNSPECIFIED = 0,
+  CounterDescriptor_Unit_UNIT_TIME_NS = 1,
+  CounterDescriptor_Unit_UNIT_COUNT = 2,
+  CounterDescriptor_Unit_UNIT_SIZE_BYTES = 3,
+};
+
+const CounterDescriptor_Unit CounterDescriptor_Unit_MIN = CounterDescriptor_Unit_UNIT_UNSPECIFIED;
+const CounterDescriptor_Unit CounterDescriptor_Unit_MAX = CounterDescriptor_Unit_UNIT_SIZE_BYTES;
+
+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,
+  };
+  using BuiltinCounterType = ::perfetto::protos::pbzero::CounterDescriptor_BuiltinCounterType;
+  using Unit = ::perfetto::protos::pbzero::CounterDescriptor_Unit;
+  static const BuiltinCounterType COUNTER_UNSPECIFIED = CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED;
+  static const BuiltinCounterType COUNTER_THREAD_TIME_NS = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_TIME_NS;
+  static const BuiltinCounterType COUNTER_THREAD_INSTRUCTION_COUNT = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT;
+  static const Unit UNIT_UNSPECIFIED = CounterDescriptor_Unit_UNIT_UNSPECIFIED;
+  static const Unit UNIT_TIME_NS = CounterDescriptor_Unit_UNIT_TIME_NS;
+  static const Unit UNIT_COUNT = CounterDescriptor_Unit_UNIT_COUNT;
+  static const Unit UNIT_SIZE_BYTES = CounterDescriptor_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Categories kCategories() { return {}; }
+  void add_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Categories::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Unit kUnit() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UnitName kUnitName() { return {}; }
+  void set_unit_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_UnitName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UnitMultiplier kUnitMultiplier() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IsIncremental kIsIncremental() { return {}; }
+  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/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;
+enum DebugAnnotation_NestedValue_NestedType : int32_t;
+
+enum DebugAnnotation_NestedValue_NestedType : int32_t {
+  DebugAnnotation_NestedValue_NestedType_UNSPECIFIED = 0,
+  DebugAnnotation_NestedValue_NestedType_DICT = 1,
+  DebugAnnotation_NestedValue_NestedType_ARRAY = 2,
+};
+
+const DebugAnnotation_NestedValue_NestedType DebugAnnotation_NestedValue_NestedType_MIN = DebugAnnotation_NestedValue_NestedType_UNSPECIFIED;
+const DebugAnnotation_NestedValue_NestedType DebugAnnotation_NestedValue_NestedType_MAX = DebugAnnotation_NestedValue_NestedType_ARRAY;
+
+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,
+  };
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DebugAnnotationName>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Iid kIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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=*/12, /*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_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_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_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,
+    kStringValueFieldNumber = 6,
+    kPointerValueFieldNumber = 7,
+    kNestedValueFieldNumber = 8,
+    kLegacyJsonValueFieldNumber = 9,
+    kDictEntriesFieldNumber = 11,
+    kArrayValuesFieldNumber = 12,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NameIid kNameIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BoolValue kBoolValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UintValue kUintValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IntValue kIntValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DoubleValue kDoubleValue() { return {}; }
+  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,
+      DebugAnnotation>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StringValue kStringValue() { return {}; }
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, 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,
+      DebugAnnotation>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PointerValue kPointerValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NestedValue kNestedValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LegacyJsonValue kLegacyJsonValue() { return {}; }
+  void set_legacy_json_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LegacyJsonValue::kFieldId, data, 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_DictEntries =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotation,
+      DebugAnnotation>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DictEntries kDictEntries() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ArrayValues kArrayValues() { return {}; }
+  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,
+  };
+  using NestedType = ::perfetto::protos::pbzero::DebugAnnotation_NestedValue_NestedType;
+  static const NestedType UNSPECIFIED = DebugAnnotation_NestedValue_NestedType_UNSPECIFIED;
+  static const NestedType DICT = DebugAnnotation_NestedValue_NestedType_DICT;
+  static const NestedType ARRAY = DebugAnnotation_NestedValue_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NestedType kNestedType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DictKeys kDictKeys() { return {}; }
+  void add_dict_keys(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DictKeys::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DictValues kDictValues() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ArrayValues kArrayValues() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IntValue kIntValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DoubleValue kDoubleValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BoolValue kBoolValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StringValue kStringValue() { return {}; }
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, 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/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 {
+
+
+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,
+  };
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LogMessageBody>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Iid kIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Body kBody() { return {}; }
+  void set_body(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Body::kFieldId, data, 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=*/2, /*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(); }
+};
+
+class LogMessage : public ::protozero::Message {
+ public:
+  using Decoder = LogMessage_Decoder;
+  enum : int32_t {
+    kSourceLocationIidFieldNumber = 1,
+    kBodyIidFieldNumber = 2,
+  };
+
+  using FieldMetadata_SourceLocationIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LogMessage>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SourceLocationIid kSourceLocationIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BodyIid kBodyIid() { return {}; }
+  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);
+  }
+};
+
+} // 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 {
+
+enum ProcessDescriptor_ChromeProcessType : int32_t;
+
+enum ProcessDescriptor_ChromeProcessType : int32_t {
+  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,
+};
+
+const ProcessDescriptor_ChromeProcessType ProcessDescriptor_ChromeProcessType_MIN = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
+const ProcessDescriptor_ChromeProcessType ProcessDescriptor_ChromeProcessType_MAX = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER;
+
+class ProcessDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*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(); }
+};
+
+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,
+  };
+  using ChromeProcessType = ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType;
+  static const ChromeProcessType PROCESS_UNSPECIFIED = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
+  static const ChromeProcessType PROCESS_BROWSER = ProcessDescriptor_ChromeProcessType_PROCESS_BROWSER;
+  static const ChromeProcessType PROCESS_RENDERER = ProcessDescriptor_ChromeProcessType_PROCESS_RENDERER;
+  static const ChromeProcessType PROCESS_UTILITY = ProcessDescriptor_ChromeProcessType_PROCESS_UTILITY;
+  static const ChromeProcessType PROCESS_ZYGOTE = ProcessDescriptor_ChromeProcessType_PROCESS_ZYGOTE;
+  static const ChromeProcessType PROCESS_SANDBOX_HELPER = ProcessDescriptor_ChromeProcessType_PROCESS_SANDBOX_HELPER;
+  static const ChromeProcessType PROCESS_GPU = ProcessDescriptor_ChromeProcessType_PROCESS_GPU;
+  static const ChromeProcessType PROCESS_PPAPI_PLUGIN = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_PLUGIN;
+  static const ChromeProcessType PROCESS_PPAPI_BROKER = ProcessDescriptor_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cmdline kCmdline() { return {}; }
+  void add_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessName kProcessName() { return {}; }
+  void set_process_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProcessName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessPriority kProcessPriority() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StartTimestampNs kStartTimestampNs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeProcessType kChromeProcessType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LegacySortIndex kLegacySortIndex() { return {}; }
+  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/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,
+  };
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SourceLocation>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Iid kIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FileName kFileName() { return {}; }
+  void set_file_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FileName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FunctionName kFunctionName() { return {}; }
+  void set_function_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FunctionName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LineNumber kLineNumber() { return {}; }
+  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);
+  }
+};
+
+} // 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,
+  };
+
+  using FieldMetadata_PostedFromIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TaskExecution>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PostedFromIid kPostedFromIid() { return {}; }
+  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 {
+
+enum ThreadDescriptor_ChromeThreadType : int32_t;
+
+enum ThreadDescriptor_ChromeThreadType : int32_t {
+  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,
+};
+
+const ThreadDescriptor_ChromeThreadType ThreadDescriptor_ChromeThreadType_MIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
+const ThreadDescriptor_ChromeThreadType ThreadDescriptor_ChromeThreadType_MAX = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER;
+
+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,
+  };
+  using ChromeThreadType = ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType;
+  static const ChromeThreadType CHROME_THREAD_UNSPECIFIED = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
+  static const ChromeThreadType CHROME_THREAD_MAIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MAIN;
+  static const ChromeThreadType CHROME_THREAD_IO = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_IO;
+  static const ChromeThreadType CHROME_THREAD_POOL_BG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_WORKER;
+  static const ChromeThreadType CHROME_THREAD_POOL_FG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FG_WORKER;
+  static const ChromeThreadType CHROME_THREAD_POOL_FB_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FB_BLOCKING;
+  static const ChromeThreadType CHROME_THREAD_POOL_BG_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_BLOCKING;
+  static const ChromeThreadType CHROME_THREAD_POOL_SERVICE = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_SERVICE;
+  static const ChromeThreadType CHROME_THREAD_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR;
+  static const ChromeThreadType CHROME_THREAD_VIZ_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_VIZ_COMPOSITOR;
+  static const ChromeThreadType CHROME_THREAD_COMPOSITOR_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR_WORKER;
+  static const ChromeThreadType CHROME_THREAD_SERVICE_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SERVICE_WORKER;
+  static const ChromeThreadType CHROME_THREAD_MEMORY_INFRA = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MEMORY_INFRA;
+  static const ChromeThreadType CHROME_THREAD_SAMPLING_PROFILER = ThreadDescriptor_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tid kTid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadName kThreadName() { return {}; }
+  void set_thread_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ThreadName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeThreadType kChromeThreadType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReferenceTimestampUs kReferenceTimestampUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReferenceThreadTimeUs kReferenceThreadTimeUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReferenceThreadInstructionCount kReferenceThreadInstructionCount() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LegacySortIndex kLegacySortIndex() { return {}; }
+  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/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=*/8, /*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(); }
+};
+
+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,
+  };
+
+  using FieldMetadata_Uuid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackDescriptor>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Uuid kUuid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ParentUuid kParentUuid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Process kProcess() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeProcess kChromeProcess() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Thread kThread() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeThread kChromeThread() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Counter kCounter() { return {}; }
+  template <typename T = CounterDescriptor> T* set_counter() {
+    return BeginNestedMessage<T>(8);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/track_event.pbzero.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 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 SourceLocation;
+class TaskExecution;
+class TrackEvent_LegacyEvent;
+enum TrackEvent_LegacyEvent_FlowDirection : int32_t;
+enum TrackEvent_LegacyEvent_InstantEventScope : int32_t;
+enum TrackEvent_Type : int32_t;
+
+enum TrackEvent_Type : int32_t {
+  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,
+};
+
+const TrackEvent_Type TrackEvent_Type_MIN = TrackEvent_Type_TYPE_UNSPECIFIED;
+const TrackEvent_Type TrackEvent_Type_MAX = TrackEvent_Type_TYPE_COUNTER;
+
+enum TrackEvent_LegacyEvent_FlowDirection : int32_t {
+  TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED = 0,
+  TrackEvent_LegacyEvent_FlowDirection_FLOW_IN = 1,
+  TrackEvent_LegacyEvent_FlowDirection_FLOW_OUT = 2,
+  TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT = 3,
+};
+
+const TrackEvent_LegacyEvent_FlowDirection TrackEvent_LegacyEvent_FlowDirection_MIN = TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED;
+const TrackEvent_LegacyEvent_FlowDirection TrackEvent_LegacyEvent_FlowDirection_MAX = TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT;
+
+enum TrackEvent_LegacyEvent_InstantEventScope : int32_t {
+  TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED = 0,
+  TrackEvent_LegacyEvent_InstantEventScope_SCOPE_GLOBAL = 1,
+  TrackEvent_LegacyEvent_InstantEventScope_SCOPE_PROCESS = 2,
+  TrackEvent_LegacyEvent_InstantEventScope_SCOPE_THREAD = 3,
+};
+
+const TrackEvent_LegacyEvent_InstantEventScope TrackEvent_LegacyEvent_InstantEventScope_MIN = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED;
+const TrackEvent_LegacyEvent_InstantEventScope TrackEvent_LegacyEvent_InstantEventScope_MAX = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_THREAD;
+
+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,
+  };
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      EventName>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Iid kIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      EventCategory>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Iid kIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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,
+  };
+
+  using FieldMetadata_TrackUuid =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEventDefaults>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrackUuid kTrackUuid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExtraCounterTrackUuids kExtraCounterTrackUuids() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExtraDoubleCounterTrackUuids kExtraDoubleCounterTrackUuids() { return {}; }
+  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=*/46, /*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() const { return at<36>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> flow_ids() const { return GetRepeated<uint64_t>(36); }
+  bool has_terminating_flow_ids() const { return at<42>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> terminating_flow_ids() const { return GetRepeated<uint64_t>(42); }
+  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_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,
+    kFlowIdsFieldNumber = 36,
+    kTerminatingFlowIdsFieldNumber = 42,
+    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,
+    kSourceLocationFieldNumber = 33,
+    kSourceLocationIidFieldNumber = 34,
+    kChromeMessagePumpFieldNumber = 35,
+    kChromeMojoEventInfoFieldNumber = 38,
+    kTimestampDeltaUsFieldNumber = 1,
+    kTimestampAbsoluteUsFieldNumber = 16,
+    kThreadTimeDeltaUsFieldNumber = 2,
+    kThreadTimeAbsoluteUsFieldNumber = 17,
+    kThreadInstructionCountDeltaFieldNumber = 8,
+    kThreadInstructionCountAbsoluteFieldNumber = 20,
+    kLegacyEventFieldNumber = 6,
+  };
+  using LegacyEvent = ::perfetto::protos::pbzero::TrackEvent_LegacyEvent;
+  using Type = ::perfetto::protos::pbzero::TrackEvent_Type;
+  static const Type TYPE_UNSPECIFIED = TrackEvent_Type_TYPE_UNSPECIFIED;
+  static const Type TYPE_SLICE_BEGIN = TrackEvent_Type_TYPE_SLICE_BEGIN;
+  static const Type TYPE_SLICE_END = TrackEvent_Type_TYPE_SLICE_END;
+  static const Type TYPE_INSTANT = TrackEvent_Type_TYPE_INSTANT;
+  static const Type TYPE_COUNTER = TrackEvent_Type_TYPE_COUNTER;
+
+  using FieldMetadata_CategoryIids =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CategoryIids kCategoryIids() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Categories kCategories() { return {}; }
+  void add_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Categories::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NameIid kNameIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Type kType() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrackUuid kTrackUuid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CounterValue kCounterValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DoubleCounterValue kDoubleCounterValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExtraCounterTrackUuids kExtraCounterTrackUuids() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExtraCounterValues kExtraCounterValues() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExtraDoubleCounterTrackUuids kExtraDoubleCounterTrackUuids() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExtraDoubleCounterValues kExtraDoubleCounterValues() { return {}; }
+  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_FlowIds =
+    ::protozero::proto_utils::FieldMetadata<
+      36,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FlowIds kFlowIds() { return {}; }
+  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::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TerminatingFlowIds =
+    ::protozero::proto_utils::FieldMetadata<
+      42,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TerminatingFlowIds kTerminatingFlowIds() { return {}; }
+  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::kUint64>
+        ::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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DebugAnnotations kDebugAnnotations() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TaskExecution kTaskExecution() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LogMessage kLogMessage() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CcSchedulerState kCcSchedulerState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeUserEvent kChromeUserEvent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeKeyedService kChromeKeyedService() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeLegacyIpc kChromeLegacyIpc() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeHistogramSample kChromeHistogramSample() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeLatencyInfo kChromeLatencyInfo() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeFrameReporter kChromeFrameReporter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeApplicationStateInfo kChromeApplicationStateInfo() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeRendererSchedulerState kChromeRendererSchedulerState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeWindowHandleEventInfo kChromeWindowHandleEventInfo() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeContentSettingsEventInfo kChromeContentSettingsEventInfo() { return {}; }
+  template <typename T = ChromeContentSettingsEventInfo> T* set_chrome_content_settings_event_info() {
+    return BeginNestedMessage<T>(43);
+  }
+
+
+  using FieldMetadata_SourceLocation =
+    ::protozero::proto_utils::FieldMetadata<
+      33,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SourceLocation,
+      TrackEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SourceLocation kSourceLocation() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SourceLocationIid kSourceLocationIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeMessagePump kChromeMessagePump() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeMojoEventInfo kChromeMojoEventInfo() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TimestampDeltaUs kTimestampDeltaUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TimestampAbsoluteUs kTimestampAbsoluteUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadTimeDeltaUs kThreadTimeDeltaUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadTimeAbsoluteUs kThreadTimeAbsoluteUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadInstructionCountDelta kThreadInstructionCountDelta() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadInstructionCountAbsolute kThreadInstructionCountAbsolute() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LegacyEvent kLegacyEvent() { return {}; }
+  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,
+  };
+  using FlowDirection = ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection;
+  using InstantEventScope = ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope;
+  static const FlowDirection FLOW_UNSPECIFIED = TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED;
+  static const FlowDirection FLOW_IN = TrackEvent_LegacyEvent_FlowDirection_FLOW_IN;
+  static const FlowDirection FLOW_OUT = TrackEvent_LegacyEvent_FlowDirection_FLOW_OUT;
+  static const FlowDirection FLOW_INOUT = TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT;
+  static const InstantEventScope SCOPE_UNSPECIFIED = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED;
+  static const InstantEventScope SCOPE_GLOBAL = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_GLOBAL;
+  static const InstantEventScope SCOPE_PROCESS = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_PROCESS;
+  static const InstantEventScope SCOPE_THREAD = TrackEvent_LegacyEvent_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NameIid kNameIid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Phase kPhase() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DurationUs kDurationUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadDurationUs kThreadDurationUs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadInstructionDelta kThreadInstructionDelta() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UnscopedId kUnscopedId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LocalId kLocalId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GlobalId kGlobalId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IdScope kIdScope() { return {}; }
+  void set_id_scope(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_IdScope::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UseAsyncTts kUseAsyncTts() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BindId kBindId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BindToEnclosing kBindToEnclosing() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FlowDirection kFlowDirection() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InstantEventScope kInstantEventScope() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PidOverride kPidOverride() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TidOverride kTidOverride() { return {}; }
+  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.
+// 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 EventCategory;
+class EventName;
+class Frame;
+class HistogramName;
+class InternedGpuRenderStageSpecification;
+class InternedGraphicsContext;
+class InternedString;
+class LogMessageBody;
+class Mapping;
+class ProfiledFrameSymbols;
+class SourceLocation;
+
+class InternedData_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/26, /*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_source_locations() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> source_locations() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  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); }
+};
+
+class InternedData : public ::protozero::Message {
+ public:
+  using Decoder = InternedData_Decoder;
+  enum : int32_t {
+    kEventCategoriesFieldNumber = 1,
+    kEventNamesFieldNumber = 2,
+    kDebugAnnotationNamesFieldNumber = 3,
+    kSourceLocationsFieldNumber = 4,
+    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,
+  };
+
+  using FieldMetadata_EventCategories =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EventCategory,
+      InternedData>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EventCategories kEventCategories() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EventNames kEventNames() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DebugAnnotationNames kDebugAnnotationNames() { return {}; }
+  template <typename T = DebugAnnotationName> T* add_debug_annotation_names() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_SourceLocations =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SourceLocation,
+      InternedData>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SourceLocations kSourceLocations() { return {}; }
+  template <typename T = SourceLocation> T* add_source_locations() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_LogMessageBody =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LogMessageBody,
+      InternedData>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LogMessageBody kLogMessageBody() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HistogramNames kHistogramNames() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_BuildIds kBuildIds() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MappingPaths kMappingPaths() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SourcePaths kSourcePaths() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FunctionNames kFunctionNames() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProfiledFrameSymbols kProfiledFrameSymbols() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Mappings kMappings() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Frames kFrames() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Callstacks kCallstacks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VulkanMemoryKeys kVulkanMemoryKeys() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GraphicsContexts kGraphicsContexts() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuSpecifications kGpuSpecifications() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_KernelSymbols kKernelSymbols() { return {}; }
+  template <typename T = InternedString> T* add_kernel_symbols() {
+    return BeginNestedMessage<T>(26);
+  }
+
+};
+
+} // 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_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*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_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(); }
+  uint32_t event_duration_ns() const { return at<3>().as_uint32(); }
+  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); }
+};
+
+class PerfettoMetatrace : public ::protozero::Message {
+ public:
+  using Decoder = PerfettoMetatrace_Decoder;
+  enum : int32_t {
+    kEventIdFieldNumber = 1,
+    kCounterIdFieldNumber = 2,
+    kEventNameFieldNumber = 8,
+    kCounterNameFieldNumber = 9,
+    kEventDurationNsFieldNumber = 3,
+    kCounterValueFieldNumber = 4,
+    kThreadIdFieldNumber = 5,
+    kHasOverrunsFieldNumber = 6,
+    kArgsFieldNumber = 7,
+  };
+  using Arg = ::perfetto::protos::pbzero::PerfettoMetatrace_Arg;
+
+  using FieldMetadata_EventId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfettoMetatrace>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EventId kEventId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CounterId kCounterId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EventName kEventName() { return {}; }
+  void set_event_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EventName::kFieldId, data, 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_CounterName =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfettoMetatrace>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CounterName kCounterName() { return {}; }
+  void set_counter_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_CounterName::kFieldId, data, 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::kUint32,
+      uint32_t,
+      PerfettoMetatrace>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EventDurationNs kEventDurationNs() { return {}; }
+  void set_event_duration_ns(uint32_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::kUint32>
+        ::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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CounterValue kCounterValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadId kThreadId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HasOverruns kHasOverruns() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Args kArgs() { return {}; }
+  template <typename T = PerfettoMetatrace_Arg> T* add_args() {
+    return BeginNestedMessage<T>(7);
+  }
+
+};
+
+class PerfettoMetatrace_Arg_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*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_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class PerfettoMetatrace_Arg : public ::protozero::Message {
+ public:
+  using Decoder = PerfettoMetatrace_Arg_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfettoMetatrace_Arg>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Key kKey() { return {}; }
+  void set_key(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Key::kFieldId, data, 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,
+      PerfettoMetatrace_Arg>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Value kValue() { return {}; }
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, 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/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,
+  };
+
+  using FieldMetadata_TracingStarted =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceEvent>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TracingStarted kTracingStarted() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllDataSourcesStarted kAllDataSourcesStarted() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllDataSourcesFlushed kAllDataSourcesFlushed() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ReadTracingBuffersCompleted kReadTracingBuffersCompleted() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TracingDisabled kTracingDisabled() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SeizedForBugreport kSeizedForBugreport() { return {}; }
+  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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EnergyConsumerDescriptor kEnergyConsumerDescriptor() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EnergyConsumerId kEnergyConsumerId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EnergyUws kEnergyUws() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PerUidBreakdown kPerUidBreakdown() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidEnergyEstimationBreakdown_EnergyUidBreakdown>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Uid kUid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EnergyUws kEnergyUws() { return {}; }
+  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/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=*/4, /*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(); }
+};
+
+class BatteryCounters : public ::protozero::Message {
+ public:
+  using Decoder = BatteryCounters_Decoder;
+  enum : int32_t {
+    kChargeCounterUahFieldNumber = 1,
+    kCapacityPercentFieldNumber = 2,
+    kCurrentUaFieldNumber = 3,
+    kCurrentAvgUaFieldNumber = 4,
+  };
+
+  using FieldMetadata_ChargeCounterUah =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BatteryCounters>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChargeCounterUah kChargeCounterUah() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CapacityPercent kCapacityPercent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CurrentUa kCurrentUa() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CurrentAvgUa kCurrentAvgUa() { return {}; }
+  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);
+  }
+};
+
+} // 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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RailDescriptor kRailDescriptor() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_EnergyData kEnergyData() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PowerRails_EnergyData>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Index kIndex() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TimestampMs kTimestampMs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Energy kEnergy() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PowerRails_RailDescriptor>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Index kIndex() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RailName kRailName() { return {}; }
+  void set_rail_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_RailName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SubsysName kSubsysName() { return {}; }
+  void set_subsys_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SubsysName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SamplingRate kSamplingRate() { return {}; }
+  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_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,
+  };
+  using Thread = ::perfetto::protos::pbzero::ProcessStats_Thread;
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Processes kProcesses() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CollectionEndTimestamp kCollectionEndTimestamp() { return {}; }
+  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=*/14, /*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(); }
+};
+
+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,
+  };
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessStats_Process>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VmSizeKb kVmSizeKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VmRssKb kVmRssKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RssAnonKb kRssAnonKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RssFileKb kRssFileKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RssShmemKb kRssShmemKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VmSwapKb kVmSwapKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VmLockedKb kVmLockedKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VmHwmKb kVmHwmKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OomScoreAdj kOomScoreAdj() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Threads kThreads() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IsPeakRssResettable kIsPeakRssResettable() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromePrivateFootprintKb kChromePrivateFootprintKb() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromePeakResidentSetKb kChromePeakResidentSetKb() { return {}; }
+  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);
+  }
+};
+
+class ProcessStats_Thread_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ 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(); }
+  bool has_cpu_freq_indices() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> cpu_freq_indices() const { return GetRepeated<uint32_t>(2); }
+  bool has_cpu_freq_ticks() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> cpu_freq_ticks() const { return GetRepeated<uint64_t>(3); }
+  bool has_cpu_freq_full() const { return at<4>().valid(); }
+  bool cpu_freq_full() const { return at<4>().as_bool(); }
+};
+
+class ProcessStats_Thread : public ::protozero::Message {
+ public:
+  using Decoder = ProcessStats_Thread_Decoder;
+  enum : int32_t {
+    kTidFieldNumber = 1,
+    kCpuFreqIndicesFieldNumber = 2,
+    kCpuFreqTicksFieldNumber = 3,
+    kCpuFreqFullFieldNumber = 4,
+  };
+
+  using FieldMetadata_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessStats_Thread>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tid kTid() { return {}; }
+  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_CpuFreqIndices =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ProcessStats_Thread>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuFreqIndices kCpuFreqIndices() { return {}; }
+  void add_cpu_freq_indices(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuFreqIndices::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CpuFreqTicks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Thread>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuFreqTicks kCpuFreqTicks() { return {}; }
+  void add_cpu_freq_ticks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuFreqTicks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CpuFreqFull =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProcessStats_Thread>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuFreqFull kCpuFreqFull() { return {}; }
+  void set_cpu_freq_full(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuFreqFull::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/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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Processes kProcesses() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Threads kThreads() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CollectionEndTimestamp kCollectionEndTimestamp() { return {}; }
+  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=*/5, /*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(); }
+};
+
+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,
+  };
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessTree_Process>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Ppid kPpid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cmdline kCmdline() { return {}; }
+  void add_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadsDeprecated kThreadsDeprecated() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Uid kUid() { return {}; }
+  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);
+  }
+};
+
+class ProcessTree_Thread_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ 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(); }
+};
+
+class ProcessTree_Thread : public ::protozero::Message {
+ public:
+  using Decoder = ProcessTree_Thread_Decoder;
+  enum : int32_t {
+    kTidFieldNumber = 1,
+    kTgidFieldNumber = 3,
+    kNameFieldNumber = 2,
+  };
+
+  using FieldMetadata_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessTree_Thread>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tid kTid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Tgid kTgid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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/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_CpuTimes;
+class SysStats_DevfreqValue;
+class SysStats_InterruptCount;
+class SysStats_MeminfoValue;
+class SysStats_VmstatValue;
+enum MeminfoCounters : int32_t;
+enum VmstatCounters : int32_t;
+
+class SysStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*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); }
+};
+
+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,
+  };
+  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 FieldMetadata_Meminfo =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats_MeminfoValue,
+      SysStats>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Meminfo kMeminfo() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Vmstat kVmstat() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuStat kCpuStat() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NumForks kNumForks() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NumIrqTotal kNumIrqTotal() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NumIrq kNumIrq() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NumSoftirqTotal kNumSoftirqTotal() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NumSoftirq kNumSoftirq() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CollectionEndTimestamp kCollectionEndTimestamp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Devfreq kDevfreq() { return {}; }
+  template <typename T = SysStats_DevfreqValue> T* add_devfreq() {
+    return BeginNestedMessage<T>(10);
+  }
+
+};
+
+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,
+  };
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SysStats_DevfreqValue>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Key kKey() { return {}; }
+  void set_key(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Key::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Value kValue() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Irq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SysStats_InterruptCount>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Irq kIrq() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Count kCount() { return {}; }
+  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_ice_ns() const { return at<3>().valid(); }
+  uint64_t user_ice_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,
+    kUserIceNsFieldNumber = 3,
+    kSystemModeNsFieldNumber = 4,
+    kIdleNsFieldNumber = 5,
+    kIoWaitNsFieldNumber = 6,
+    kIrqNsFieldNumber = 7,
+    kSoftirqNsFieldNumber = 8,
+  };
+
+  using FieldMetadata_CpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStats_CpuTimes>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuId kCpuId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UserNs kUserNs() { return {}; }
+  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_UserIceNs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_CpuTimes>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UserIceNs kUserIceNs() { return {}; }
+  void set_user_ice_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UserIceNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SystemModeNs kSystemModeNs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IdleNs kIdleNs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IoWaitNs kIoWaitNs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IrqNs kIrqNs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SoftirqNs kSoftirqNs() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::VmstatCounters,
+      SysStats_VmstatValue>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Key kKey() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Value kValue() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::MeminfoCounters,
+      SysStats_MeminfoValue>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Key kKey() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Value kValue() { return {}; }
+  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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cpus kCpus() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Processor =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CpuInfo_Cpu>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Processor kProcessor() { return {}; }
+  void set_processor(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Processor::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Frequencies kFrequencies() { return {}; }
+  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/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,
+  };
+
+  using FieldMetadata_TimestampClockId =
+    ::protozero::proto_utils::FieldMetadata<
+      58,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracePacketDefaults>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TimestampClockId kTimestampClockId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrackEventDefaults kTrackEventDefaults() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PerfSampleDefaults kPerfSampleDefaults() { return {}; }
+  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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Str kStr() { return {}; }
+  void set_str(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Str::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SeqValue kSeqValue() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Counter kCounter() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IsLast kIsLast() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Payload kPayload() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Str =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestEvent_TestPayload>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Str kStr() { return {}; }
+  void add_str(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Str::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Nested kNested() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SingleString kSingleString() { return {}; }
+  void set_single_string(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SingleString::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SingleInt kSingleInt() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RepeatedInts kRepeatedInts() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_RemainingNestingDepth kRemainingNestingDepth() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DebugAnnotations kDebugAnnotations() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_ChildFieldForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestExtensionChild>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChildFieldForTesting kChildFieldForTesting() { return {}; }
+  void set_child_field_for_testing(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ChildFieldForTesting::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DebugAnnotations kDebugAnnotations() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StringExtensionForTesting kStringExtensionForTesting() { return {}; }
+  void set_string_extension_for_testing(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringExtensionForTesting::kFieldId, data, 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_IntExtensionForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      9901,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TestExtension>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IntExtensionForTesting kIntExtensionForTesting() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_OmittedExtensionForTesting kOmittedExtensionForTesting() { return {}; }
+  void set_omitted_extension_for_testing(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_OmittedExtensionForTesting::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_NestedMessageExtensionForTesting kNestedMessageExtensionForTesting() { return {}; }
+  template <typename T = TestExtensionChild> T* set_nested_message_extension_for_testing() {
+    return BeginNestedMessage<T>(9903);
+  }
+
+};
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// 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 AndroidEnergyEstimationBreakdown;
+class AndroidLogPacket;
+class BatteryCounters;
+class ChromeBenchmarkMetadata;
+class ChromeEventBundle;
+class ChromeMetadataPacket;
+class ClockSnapshot;
+class CpuInfo;
+class DeobfuscationMapping;
+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 MemoryTrackerSnapshot;
+class ModuleSymbols;
+class PackagesList;
+class PerfSample;
+class PerfettoMetatrace;
+class PowerRails;
+class ProcessDescriptor;
+class ProcessStats;
+class ProcessTree;
+class ProfilePacket;
+class ProfiledFrameSymbols;
+class SmapsPacket;
+class StreamingAllocation;
+class StreamingFree;
+class StreamingProfilePacket;
+class SysStats;
+class SystemInfo;
+class TestEvent;
+class ThreadDescriptor;
+class TraceConfig;
+class TracePacketDefaults;
+class TraceStats;
+class TracingServiceEvent;
+class TrackDescriptor;
+class TrackEvent;
+class Trigger;
+class UiState;
+class VulkanApiEvent;
+class VulkanMemoryEvent;
+
+enum TracePacket_SequenceFlags : int32_t {
+  TracePacket_SequenceFlags_SEQ_UNSPECIFIED = 0,
+  TracePacket_SequenceFlags_SEQ_INCREMENTAL_STATE_CLEARED = 1,
+  TracePacket_SequenceFlags_SEQ_NEEDS_INCREMENTAL_STATE = 2,
+};
+
+const TracePacket_SequenceFlags TracePacket_SequenceFlags_MIN = TracePacket_SequenceFlags_SEQ_UNSPECIFIED;
+const TracePacket_SequenceFlags TracePacket_SequenceFlags_MAX = TracePacket_SequenceFlags_SEQ_NEEDS_INCREMENTAL_STATE;
+
+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_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_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_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_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(); }
+};
+
+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,
+    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,
+    kProfiledFrameSymbolsFieldNumber = 55,
+    kModuleSymbolsFieldNumber = 61,
+    kDeobfuscationMappingFieldNumber = 64,
+    kTrackDescriptorFieldNumber = 60,
+    kProcessDescriptorFieldNumber = 43,
+    kThreadDescriptorFieldNumber = 44,
+    kFtraceEventsFieldNumber = 1,
+    kSynchronizationMarkerFieldNumber = 36,
+    kCompressedPacketsFieldNumber = 50,
+    kExtensionDescriptorFieldNumber = 72,
+    kForTestingFieldNumber = 900,
+    kTrustedUidFieldNumber = 3,
+    kTrustedPacketSequenceIdFieldNumber = 10,
+    kInternedDataFieldNumber = 12,
+    kSequenceFlagsFieldNumber = 13,
+    kIncrementalStateClearedFieldNumber = 41,
+    kTracePacketDefaultsFieldNumber = 59,
+    kPreviousPacketDroppedFieldNumber = 42,
+  };
+  using SequenceFlags = ::perfetto::protos::pbzero::TracePacket_SequenceFlags;
+  static const SequenceFlags SEQ_UNSPECIFIED = TracePacket_SequenceFlags_SEQ_UNSPECIFIED;
+  static const SequenceFlags SEQ_INCREMENTAL_STATE_CLEARED = TracePacket_SequenceFlags_SEQ_INCREMENTAL_STATE_CLEARED;
+  static const SequenceFlags SEQ_NEEDS_INCREMENTAL_STATE = TracePacket_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Timestamp kTimestamp() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TimestampClockId kTimestampClockId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessTree kProcessTree() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessStats kProcessStats() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InodeFileMap kInodeFileMap() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeEvents kChromeEvents() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ClockSnapshot kClockSnapshot() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SysStats kSysStats() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrackEvent kTrackEvent() { return {}; }
+  template <typename T = TrackEvent> T* set_track_event() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_TraceConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      33,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig,
+      TracePacket>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceConfig kTraceConfig() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FtraceStats kFtraceStats() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TraceStats kTraceStats() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProfilePacket kProfilePacket() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StreamingAllocation kStreamingAllocation() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StreamingFree kStreamingFree() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Battery kBattery() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PowerRails kPowerRails() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AndroidLog kAndroidLog() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SystemInfo kSystemInfo() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Trigger kTrigger() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PackagesList kPackagesList() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeBenchmarkMetadata kChromeBenchmarkMetadata() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PerfettoMetatrace kPerfettoMetatrace() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ChromeMetadata kChromeMetadata() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuCounterEvent kGpuCounterEvent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuRenderStageEvent kGpuRenderStageEvent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_StreamingProfilePacket kStreamingProfilePacket() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HeapGraph kHeapGraph() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GraphicsFrameEvent kGraphicsFrameEvent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VulkanMemoryEvent kVulkanMemoryEvent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuLog kGpuLog() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_VulkanApiEvent kVulkanApiEvent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PerfSample kPerfSample() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CpuInfo kCpuInfo() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SmapsPacket kSmapsPacket() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ServiceEvent kServiceEvent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InitialDisplayState kInitialDisplayState() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GpuMemTotalEvent kGpuMemTotalEvent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MemoryTrackerSnapshot kMemoryTrackerSnapshot() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FrameTimelineEvent kFrameTimelineEvent() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AndroidEnergyEstimationBreakdown kAndroidEnergyEstimationBreakdown() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_UiState kUiState() { return {}; }
+  template <typename T = UiState> T* set_ui_state() {
+    return BeginNestedMessage<T>(78);
+  }
+
+
+  using FieldMetadata_ProfiledFrameSymbols =
+    ::protozero::proto_utils::FieldMetadata<
+      55,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProfiledFrameSymbols,
+      TracePacket>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProfiledFrameSymbols kProfiledFrameSymbols() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ModuleSymbols kModuleSymbols() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_DeobfuscationMapping kDeobfuscationMapping() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrackDescriptor kTrackDescriptor() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessDescriptor kProcessDescriptor() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ThreadDescriptor kThreadDescriptor() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_FtraceEvents kFtraceEvents() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SynchronizationMarker kSynchronizationMarker() { return {}; }
+  void set_synchronization_marker(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_SynchronizationMarker::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_CompressedPackets kCompressedPackets() { return {}; }
+  void set_compressed_packets(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_CompressedPackets::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExtensionDescriptor kExtensionDescriptor() { return {}; }
+  template <typename T = ExtensionDescriptor> T* set_extension_descriptor() {
+    return BeginNestedMessage<T>(72);
+  }
+
+
+  using FieldMetadata_ForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      900,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TestEvent,
+      TracePacket>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ForTesting kForTesting() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrustedUid kTrustedUid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TrustedPacketSequenceId kTrustedPacketSequenceId() { return {}; }
+  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_InternedData =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedData,
+      TracePacket>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_InternedData kInternedData() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SequenceFlags kSequenceFlags() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_IncrementalStateCleared kIncrementalStateCleared() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TracePacketDefaults kTracePacketDefaults() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_PreviousPacketDropped kPreviousPacketDropped() { return {}; }
+  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);
+  }
+};
+
+} // 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,
+  };
+
+  using FieldMetadata_Packet =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TracePacket,
+      Trace>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Packet kPacket() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_ExtensionSet =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FileDescriptorSet,
+      ExtensionDescriptor>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ExtensionSet kExtensionSet() { return {}; }
+  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;
+enum MemoryTrackerSnapshot_LevelOfDetail : int32_t;
+enum MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units : int32_t;
+
+enum MemoryTrackerSnapshot_LevelOfDetail : int32_t {
+  MemoryTrackerSnapshot_LevelOfDetail_DETAIL_FULL = 0,
+  MemoryTrackerSnapshot_LevelOfDetail_DETAIL_LIGHT = 1,
+  MemoryTrackerSnapshot_LevelOfDetail_DETAIL_BACKGROUND = 2,
+};
+
+const MemoryTrackerSnapshot_LevelOfDetail MemoryTrackerSnapshot_LevelOfDetail_MIN = MemoryTrackerSnapshot_LevelOfDetail_DETAIL_FULL;
+const MemoryTrackerSnapshot_LevelOfDetail MemoryTrackerSnapshot_LevelOfDetail_MAX = MemoryTrackerSnapshot_LevelOfDetail_DETAIL_BACKGROUND;
+
+enum MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units : int32_t {
+  MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units_UNSPECIFIED = 0,
+  MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units_BYTES = 1,
+  MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units_COUNT = 2,
+};
+
+const MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units_MIN = MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units_UNSPECIFIED;
+const MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units_MAX = MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units_COUNT;
+
+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,
+  };
+  using ProcessSnapshot = ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot;
+  using LevelOfDetail = ::perfetto::protos::pbzero::MemoryTrackerSnapshot_LevelOfDetail;
+  static const LevelOfDetail DETAIL_FULL = MemoryTrackerSnapshot_LevelOfDetail_DETAIL_FULL;
+  static const LevelOfDetail DETAIL_LIGHT = MemoryTrackerSnapshot_LevelOfDetail_DETAIL_LIGHT;
+  static const LevelOfDetail DETAIL_BACKGROUND = MemoryTrackerSnapshot_LevelOfDetail_DETAIL_BACKGROUND;
+
+  using FieldMetadata_GlobalDumpId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MemoryTrackerSnapshot>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_GlobalDumpId kGlobalDumpId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_LevelOfDetail kLevelOfDetail() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ProcessMemoryDumps kProcessMemoryDumps() { return {}; }
+  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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AllocatorDumps kAllocatorDumps() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_MemoryEdges kMemoryEdges() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_SourceId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SourceId kSourceId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TargetId kTargetId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Importance kImportance() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Overridable kOverridable() { return {}; }
+  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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Id kId() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_AbsoluteName kAbsoluteName() { return {}; }
+  void set_absolute_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_AbsoluteName::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Weak kWeak() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_SizeBytes kSizeBytes() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Entries kEntries() { return {}; }
+  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,
+  };
+  using Units = ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units;
+  static const Units UNSPECIFIED = MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units_UNSPECIFIED;
+  static const Units BYTES = MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units_BYTES;
+  static const Units COUNT = MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Name kName() { return {}; }
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, 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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Units kUnits() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ValueUint64 kValueUint64() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_ValueString kValueString() { return {}; }
+  void set_value_string(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ValueString::kFieldId, data, 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,
+  };
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TimelineStartTs kTimelineStartTs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_TimelineEndTs kTimelineEndTs() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_HighlightProcess kHighlightProcess() { return {}; }
+  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,
+  };
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      UiState_HighlightProcess>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Pid kPid() { return {}; }
+  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>;
+
+  // Ceci n'est pas une pipe.
+  // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
+  // type (and users are expected to use it as such, hence kCamelCase name).
+  // It is declared as a function to keep protozero bindings header-only as
+  // inline constexpr variables are not available until C++17 (while inline
+  // functions are).
+  // TODO(altimin): Use inline variable instead after adopting C++17.  
+  static constexpr FieldMetadata_Cmdline kCmdline() { return {}; }
+  void set_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, data, 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_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 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 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 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 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 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 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 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 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 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 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 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 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;
+}  // 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,
+};
+
+class PERFETTO_EXPORT 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;
+  enum FieldNumbers {
+    kStateFieldNumber = 1,
+    kReasonFieldNumber = 2,
+    kFrameSourceFieldNumber = 3,
+    kFrameSequenceFieldNumber = 4,
+    kAffectsSmoothnessFieldNumber = 5,
+    kScrollStateFieldNumber = 6,
+    kHasMainAnimationFieldNumber = 7,
+    kHasCompositorAnimationFieldNumber = 8,
+    kHasSmoothInputMainFieldNumber = 9,
+    kHasMissingContentFieldNumber = 10,
+    kLayerTreeHostIdFieldNumber = 11,
+  };
+
+  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); }
+
+ 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_{};
+
+  // 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_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 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 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 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 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 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 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 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 ChromeMojoEventInfo : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kWatcherNotifyInterfaceTagFieldNumber = 1,
+    kIpcHashFieldNumber = 2,
+    kMojoInterfaceTagFieldNumber = 3,
+  };
+
+  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); }
+
+ private:
+  std::string watcher_notify_interface_tag_{};
+  uint32_t ipc_hash_{};
+  std::string mojo_interface_tag_{};
+
+  // 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_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,
+};
+
+class PERFETTO_EXPORT 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 ProcessType_MIN = ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED;
+  static constexpr auto ProcessType_MAX = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHAPEDETECTION;
+  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 ChromeRendererSchedulerState : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kRailModeFieldNumber = 1,
+  };
+
+  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); }
+
+ private:
+  ChromeRAILMode rail_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_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_MEMORY_INFRA = 50,
+  ChromeThreadDescriptor_ThreadType_THREAD_SAMPLING_PROFILER = 51,
+};
+
+class PERFETTO_EXPORT 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_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 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 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/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 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/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 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 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 DebugAnnotation : public ::protozero::CppMessageObj {
+ public:
+  using NestedValue = DebugAnnotation_NestedValue;
+  enum FieldNumbers {
+    kNameIidFieldNumber = 1,
+    kNameFieldNumber = 10,
+    kBoolValueFieldNumber = 2,
+    kUintValueFieldNumber = 3,
+    kIntValueFieldNumber = 4,
+    kDoubleValueFieldNumber = 5,
+    kStringValueFieldNumber = 6,
+    kPointerValueFieldNumber = 7,
+    kNestedValueFieldNumber = 8,
+    kLegacyJsonValueFieldNumber = 9,
+    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_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_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); }
+
+  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_{};
+  std::string string_value_{};
+  uint64_t pointer_value_{};
+  ::protozero::CopyablePtr<DebugAnnotation_NestedValue> nested_value_;
+  std::string legacy_json_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<13> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT 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;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT 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 LogMessage : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSourceLocationIidFieldNumber = 1,
+    kBodyIidFieldNumber = 2,
+  };
+
+  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); }
+
+ private:
+  uint64_t source_location_iid_{};
+  uint64_t body_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_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 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,
+  };
+
+  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); }
+
+ 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_{};
+
+  // 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_PROCESS_DESCRIPTOR_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;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT 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_{};
+};
+
+}  // 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 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 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_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 TrackDescriptor : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kUuidFieldNumber = 1,
+    kParentUuidFieldNumber = 5,
+    kNameFieldNumber = 2,
+    kProcessFieldNumber = 3,
+    kChromeProcessFieldNumber = 6,
+    kThreadFieldNumber = 4,
+    kChromeThreadFieldNumber = 7,
+    kCounterFieldNumber = 8,
+  };
+
+  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(); }
+
+ 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_;
+
+  // 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_TRACK_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 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 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 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 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 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 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 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,
+    kFlowIdsFieldNumber = 36,
+    kTerminatingFlowIdsFieldNumber = 42,
+    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,
+    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() 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() 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_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_;
+  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<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<47> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT 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/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 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 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/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 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/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_CompactSchedConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT FtraceConfig : public ::protozero::CppMessageObj {
+ public:
+  using CompactSchedConfig = FtraceConfig_CompactSchedConfig;
+  enum FieldNumbers {
+    kFtraceEventsFieldNumber = 1,
+    kAtraceCategoriesFieldNumber = 2,
+    kAtraceAppsFieldNumber = 3,
+    kBufferSizeKbFieldNumber = 10,
+    kDrainPeriodMsFieldNumber = 11,
+    kCompactSchedFieldNumber = 12,
+    kSymbolizeKsymsFieldNumber = 13,
+    kInitializeKsymsSynchronouslyForTestingFieldNumber = 14,
+  };
+
+  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_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_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); }
+
+ 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_;
+  bool symbolize_ksyms_{};
+  bool initialize_ksyms_synchronously_for_testing_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<15> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT 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 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 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 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 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 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,
+};
+
+class PERFETTO_EXPORT 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 BatteryCounters_MIN = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED;
+  static constexpr auto BatteryCounters_MAX = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT_AVG;
+  enum FieldNumbers {
+    kBatteryPollMsFieldNumber = 1,
+    kBatteryCountersFieldNumber = 2,
+    kCollectPowerRailsFieldNumber = 3,
+    kCollectEnergyEstimationBreakdownFieldNumber = 4,
+  };
+
+  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); }
+
+ private:
+  uint32_t battery_poll_ms_{};
+  std::vector<AndroidPowerConfig_BatteryCounters> battery_counters_;
+  bool collect_power_rails_{};
+  bool collect_energy_estimation_breakdown_{};
+
+  // 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_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 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,
+    kRecordThreadTimeInStateFieldNumber = 7,
+    kThreadTimeInStateCacheSizeFieldNumber = 8,
+  };
+
+  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_record_thread_time_in_state() const { return _has_field_[7]; }
+  bool record_thread_time_in_state() const { return record_thread_time_in_state_; }
+  void set_record_thread_time_in_state(bool value) { record_thread_time_in_state_ = value; _has_field_.set(7); }
+
+  bool has_thread_time_in_state_cache_size() const { return _has_field_[8]; }
+  uint32_t thread_time_in_state_cache_size() const { return thread_time_in_state_cache_size_; }
+  void set_thread_time_in_state_cache_size(uint32_t value) { thread_time_in_state_cache_size_ = value; _has_field_.set(8); }
+
+ 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 record_thread_time_in_state_{};
+  uint32_t thread_time_in_state_cache_size_{};
+
+  // 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_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 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 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 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 JavaHprofConfig_ContinuousDumpConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDumpPhaseMsFieldNumber = 1,
+    kDumpIntervalMsFieldNumber = 2,
+  };
+
+  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); }
+
+ 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<3> _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 PerfEvents_Counter : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT PerfEventConfig : public ::protozero::CppMessageObj {
+ public:
+  using CallstackSampling = PerfEventConfig_CallstackSampling;
+  using Scope = PerfEventConfig_Scope;
+  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 PerfEventConfig_CallstackSampling : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kScopeFieldNumber = 1,
+    kKernelFramesFieldNumber = 2,
+  };
+
+  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); }
+
+ private:
+  ::protozero::CopyablePtr<PerfEventConfig_Scope> scope_;
+  bool kernel_frames_{};
+
+  // 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 PerfEventConfig_Scope : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTargetPidFieldNumber = 1,
+    kTargetCmdlineFieldNumber = 2,
+    kExcludePidFieldNumber = 3,
+    kExcludeCmdlineFieldNumber = 4,
+    kAdditionalCmdlineCountFieldNumber = 5,
+  };
+
+  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); }
+
+ 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_{};
+
+  // 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_PROFILING_PERF_EVENT_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 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,
+  };
+
+  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); }
+
+ 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_{};
+
+  // 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_CONFIG_SYS_STATS_SYS_STATS_CONFIG_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 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/data_source_config.gen.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 ChromeConfig;
+enum DataSourceConfig_SessionInitiator : 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 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,
+    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,
+    kPackagesListConfigFieldNumber = 109,
+    kPerfEventConfigFieldNumber = 111,
+    kVulkanMemoryConfigFieldNumber = 112,
+    kTrackEventConfigFieldNumber = 113,
+    kAndroidPolledStateConfigFieldNumber = 114,
+    kChromeConfigFieldNumber = 101,
+    kInterceptorConfigFieldNumber = 115,
+    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_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& 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); }
+
+  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(); }
+
+  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_{};
+  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 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]
+  ::protozero::CopyablePtr<ChromeConfig> chrome_config_;
+  ::protozero::CopyablePtr<InterceptorConfig> interceptor_config_;
+  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_
+// 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;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT 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); }
+
+  const std::string& console_config_raw() const { return console_config_; }
+  void set_console_config_raw(const std::string& raw) { console_config_ = raw; _has_field_.set(100); }
+
+ private:
+  std::string name_{};
+  std::string console_config_;  // [lazy=true]
+
+  // 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_TraceFilter;
+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 ChromeConfig;
+class TraceConfig_BufferConfig;
+enum TraceConfig_LockdownModeOperation : int;
+enum TraceConfig_CompressionType : int;
+enum TraceConfig_StatsdLogging : int;
+enum TraceConfig_TriggerConfig_TriggerMode : int;
+enum BuiltinClock : int;
+enum DataSourceConfig_SessionInitiator : 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 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 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 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 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/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_TraceFilter;
+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 ChromeConfig;
+class TraceConfig_BufferConfig;
+enum TraceConfig_LockdownModeOperation : int;
+enum TraceConfig_CompressionType : int;
+enum TraceConfig_StatsdLogging : int;
+enum TraceConfig_TriggerConfig_TriggerMode : int;
+enum BuiltinClock : int;
+enum DataSourceConfig_SessionInitiator : 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_TriggerConfig_TriggerMode : int {
+  TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED = 0,
+  TraceConfig_TriggerConfig_TriggerMode_START_TRACING = 1,
+  TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING = 2,
+};
+enum TraceConfig_BufferConfig_FillPolicy : int {
+  TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED = 0,
+  TraceConfig_BufferConfig_FillPolicy_RING_BUFFER = 1,
+  TraceConfig_BufferConfig_FillPolicy_DISCARD = 2,
+};
+
+class PERFETTO_EXPORT 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 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,
+    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,
+    kIncidentReportConfigFieldNumber = 25,
+    kStatsdLoggingFieldNumber = 31,
+    kTraceUuidMsbFieldNumber = 27,
+    kTraceUuidLsbFieldNumber = 28,
+    kTraceFilterFieldNumber = 32,
+  };
+
+  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_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_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_[32]; }
+  const TraceConfig_TraceFilter& trace_filter() const { return *trace_filter_; }
+  TraceConfig_TraceFilter* mutable_trace_filter() { _has_field_.set(32); return trace_filter_.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 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_{};
+  ::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_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<33> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT TraceConfig_TraceFilter : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kBytecodeFieldNumber = 1,
+  };
+
+  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); }
+
+ private:
+  std::string bytecode_{};
+
+  // 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 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 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 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 TriggerMode_MIN = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
+  static constexpr auto TriggerMode_MAX = TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING;
+  enum FieldNumbers {
+    kTriggerModeFieldNumber = 1,
+    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); }
+
+  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_{};
+  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<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT 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 TraceConfig_GuardrailOverrides : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kMaxUploadPerDayBytesFieldNumber = 1,
+  };
+
+  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); }
+
+ private:
+  uint64_t max_upload_per_day_bytes_{};
+
+  // 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 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 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 TraceConfig_BuiltinDataSource : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDisableClockSnapshottingFieldNumber = 1,
+    kDisableTraceConfigFieldNumber = 2,
+    kDisableSystemInfoFieldNumber = 3,
+    kDisableServiceEventsFieldNumber = 4,
+    kPrimaryTraceClockFieldNumber = 5,
+    kSnapshotIntervalMsFieldNumber = 6,
+    kPreferSuspendClockForSnapshotFieldNumber = 7,
+  };
+
+  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); }
+
+ 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_{};
+
+  // 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 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 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,
+  };
+
+  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); }
+
+ private:
+  uint32_t size_kb_{};
+  TraceConfig_BufferConfig_FillPolicy fill_policy_{};
+
+  // 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_TRACE_CONFIG_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 SaveTraceForBugreportResponse;
+class SaveTraceForBugreportRequest;
+class QueryCapabilitiesResponse;
+class TracingServiceCapabilities;
+class QueryCapabilitiesRequest;
+class QueryServiceStateResponse;
+class TracingServiceState;
+class TracingServiceState_DataSource;
+class DataSourceDescriptor;
+class TracingServiceState_Producer;
+class QueryServiceStateRequest;
+class ObserveEventsResponse;
+class ObservableEvents;
+class ObservableEvents_DataSourceInstanceStateChange;
+class ObserveEventsRequest;
+class GetTraceStatsResponse;
+class TraceStats;
+class TraceStats_FilterStats;
+class TraceStats_BufferStats;
+class GetTraceStatsRequest;
+class AttachResponse;
+class TraceConfig;
+class TraceConfig_TraceFilter;
+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 ChromeConfig;
+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 TraceConfig_LockdownModeOperation : int;
+enum TraceConfig_CompressionType : int;
+enum TraceConfig_StatsdLogging : int;
+enum TraceConfig_TriggerConfig_TriggerMode : int;
+enum BuiltinClock : int;
+enum DataSourceConfig_SessionInitiator : 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 FlushRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTimeoutMsFieldNumber = 1,
+  };
+
+  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); }
+
+ private:
+  uint32_t timeout_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 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 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 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 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 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 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 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 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 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 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 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 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 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 ChromeConfig;
+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 RegisterDataSourceResponse;
+class RegisterDataSourceRequest;
+class DataSourceDescriptor;
+class InitializeConnectionResponse;
+class InitializeConnectionRequest;
+enum DataSourceConfig_SessionInitiator : int;
+enum ChromeConfig_ClientPriority : int;
+enum InitializeConnectionRequest_ProducerSMBScrapingMode : int;
+enum InitializeConnectionRequest_ProducerBuildFlags : 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,
+};
+enum InitializeConnectionRequest_ProducerBuildFlags : int {
+  InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_UNSPECIFIED = 0,
+  InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_ON = 1,
+  InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_OFF = 2,
+};
+
+class PERFETTO_EXPORT 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 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 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 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 GetAsyncCommandResponse_Flush : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDataSourceIdsFieldNumber = 1,
+    kRequestIdFieldNumber = 2,
+  };
+
+  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); }
+
+ private:
+  std::vector<uint64_t> data_source_ids_;
+  uint64_t request_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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 InitializeConnectionResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kUsingShmemProvidedByProducerFieldNumber = 1,
+    kDirectSmbPatchingSupportedFieldNumber = 2,
+  };
+
+  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); }
+
+ private:
+  bool using_shmem_provided_by_producer_{};
+  bool direct_smb_patching_supported_{};
+
+  // 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 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;
+  using ProducerBuildFlags = InitializeConnectionRequest_ProducerBuildFlags;
+  static constexpr auto BUILD_FLAGS_UNSPECIFIED = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_UNSPECIFIED;
+  static constexpr auto BUILD_FLAGS_DCHECKS_ON = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_ON;
+  static constexpr auto BUILD_FLAGS_DCHECKS_OFF = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_OFF;
+  static constexpr auto ProducerBuildFlags_MIN = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_UNSPECIFIED;
+  static constexpr auto ProducerBuildFlags_MAX = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_OFF;
+  enum FieldNumbers {
+    kSharedMemoryPageSizeHintBytesFieldNumber = 1,
+    kSharedMemorySizeHintBytesFieldNumber = 2,
+    kProducerNameFieldNumber = 3,
+    kSmbScrapingModeFieldNumber = 4,
+    kBuildFlagsFieldNumber = 5,
+    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_build_flags() const { return _has_field_[5]; }
+  InitializeConnectionRequest_ProducerBuildFlags build_flags() const { return build_flags_; }
+  void set_build_flags(InitializeConnectionRequest_ProducerBuildFlags value) { build_flags_ = value; _has_field_.set(5); }
+
+  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_{};
+  InitializeConnectionRequest_ProducerBuildFlags build_flags_{};
+  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_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 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;
+  enum FieldNumbers {
+    kRequestIdFieldNumber = 2,
+    kMsgBindServiceFieldNumber = 3,
+    kMsgBindServiceReplyFieldNumber = 4,
+    kMsgInvokeMethodFieldNumber = 5,
+    kMsgInvokeMethodReplyFieldNumber = 6,
+    kMsgRequestErrorFieldNumber = 7,
+    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(); }
+
+  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_;
+  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<8> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT 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 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 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 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 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 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/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/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_
+// 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 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/field.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; }
+  uint16_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(uint16_t id,
+                  uint8_t type,
+                  uint64_t int_value,
+                  uint32_t size) {
+    id_ = id;
+    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;
+
+ 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.
+  uint16_t id_;         // Proto field ordinal.
+  uint8_t type_;        // 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/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/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_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 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.
+  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 (minus |size_already_written| below). This is the mechanism
+  // used by messages to backfill their corresponding size field in the parent
+  // message.
+  uint8_t* size_field() const { return size_field_; }
+  void set_size_field(uint8_t* size_field) { size_field_ = size_field; }
+
+  // This is to deal with case of backfilling the size of a root (non-nested)
+  // message which is split into multiple chunks. Upon finalization only the
+  // partial size that lies in the last chunk has to be backfilled.
+  void inc_size_already_written(uint32_t sz) { size_already_written_ += sz; }
+
+  Message* nested_message() { return nested_message_; }
+
+  bool is_finalized() const { return finalized_; }
+
+#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) {
+    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(!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_;
+
+  // See comment for inc_size_already_written().
+  uint32_t size_already_written_;
+
+  // When true, no more changes to the message are allowed. This is to DCHECK
+  // attempts of writing to a message which has been Finalize()-d.
+  bool finalized_;
+
+#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_
+// 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 <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 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_.back().entries > 0);
+    PERFETTO_DCHECK(&blocks_.back().storage[blocks_.back().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_.back();
+    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::list<Block> blocks_;
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_MESSAGE_ARENA_H_
+// gen_amalgamated begin header: include/perfetto/protozero/message_handle.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"
+
+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 MessageHandleBase {
+ public:
+  ~MessageHandleBase();
+
+  // Move-only type.
+  MessageHandleBase(MessageHandleBase&&) noexcept;
+  MessageHandleBase& operator=(MessageHandleBase&&);
+  explicit operator bool() const {
+#if PERFETTO_DCHECK_IS_ON()
+    PERFETTO_DCHECK(!message_ || generation_ == message_->generation_);
+#endif
+    return !!message_;
+  }
+
+ protected:
+  explicit MessageHandleBase(Message* = nullptr);
+  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&&);
+
+  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_
+// 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 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_ = 0;
+
+  // 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_
+class PERFETTO_EXPORT 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 {
+    return PERFETTO_LIKELY(id < num_fields_) ? fields_[id] : 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 {
+    return RepeatedFieldIterator<T>(field_id, &fields_[num_fields_],
+                                    &fields_[size_], &fields_[field_id]);
+  }
+
+  // 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()) {
+      return PackedRepeatedFieldIterator<wire_type, cpp_type>(
+          field.data(), field.size(), parse_error_location);
+    } else {
+      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),
+        size_(num_fields),
+        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) * num_fields_);
+  }
+
+  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 fields without accounting repeated storage. This is equal to
+  // MAX_FIELD_ID + 1 (to account for the invalid 0th field).
+  // This value is always <= size_ (and hence <= capacity);
+  uint32_t num_fields_;
+
+  // Number of active |fields_| entries. This is initially equal to the highest
+  // number of fields for the message (num_fields_ == MAX_FIELD_ID + 1) and can
+  // grow up to |capacity_| in the case of repeated fields.
+  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_;
+};
+
+// 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,
+                              kCapacity,
+                              buffer,
+                              length) {
+    static_assert(MAX_FIELD_ID <= kMaxDecoderFieldId, "Field ordinal too high");
+    TypedProtoDecoderBase::ParseAllFields();
+  }
+
+  template <uint32_t FIELD_ID>
+  const Field& at() const {
+    static_assert(FIELD_ID <= MAX_FIELD_ID, "FIELD_ID > MAX_FIELD_ID");
+    return fields_[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:
+  // In the case of non-repeated fields, this constant defines the highest field
+  // id we are able to decode. This is to limit the on-stack storage.
+  // In the case of repeated fields, this constant defines the max number of
+  // repeated fields that we'll be able to store before falling back on the
+  // heap. Keep this value in sync with the one in protozero_generator.cc.
+  static constexpr size_t kMaxDecoderFieldId = 999;
+
+  // If we the message has no repeated fields we need at most N Field entries
+  // in the on-stack storage, where N is the highest field id.
+  // Otherwise we need some room to store repeated fields.
+  static constexpr size_t kCapacity =
+      1 + (HAS_NONPACKED_REPEATED_FIELDS ? kMaxDecoderFieldId : MAX_FIELD_ID);
+
+  Field on_stack_storage_[kCapacity];
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_PROTO_DECODER_H_
+// gen_amalgamated begin header: include/perfetto/protozero/proto_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"
+
+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;
+
+// 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 and 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>
+inline uint8_t* WriteVarInt(T value, uint8_t* target) {
+  // 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);
+
+  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) {
+  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 |= 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;
+}
+
+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 internal {
+
+// Ideally we would create variables of FieldMetadata<...> type directly,
+// but before C++17's support for constexpr inline variables arrive, we have to
+// actually use pointers to inline functions instead to avoid having to define
+// symbols in *.pbzero.cc files.
+//
+// Note: protozero bindings will generate Message::kFieldName variable and which
+// can then be passed to TRACE_EVENT macro for inline writing of typed messages.
+// The fact that the former can be passed to the latter is a part of the stable
+// API, while the particular type is not and users should not rely on it.
+template <typename T>
+using FieldMetadataHelper = T (*)(void);
+
+}  // namespace internal
+}  // namespace proto_utils
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_PROTO_UTILS_H_
+// gen_amalgamated begin header: include/perfetto/protozero/root_message.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_
+// gen_amalgamated begin header: include/perfetto/protozero/scattered_heap_buffer.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 ScatteredHeapBuffer
+    : public protozero::ScatteredStreamWriter::Delegate {
+ public:
+  class PERFETTO_EXPORT 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/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 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/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>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.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 ScatteredStreamWriter {
+ public:
+  class PERFETTO_EXPORT Delegate {
+   public:
+    virtual ~Delegate();
+    virtual ContiguousMemoryRange GetNewBuffer() = 0;
+  };
+
+  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 memcpy 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);
+    memcpy(write_ptr_, src, size);
+    write_ptr_ = end;
+  }
+
+  inline void WriteBytes(const uint8_t* src, size_t size) {
+    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;
+  }
+
+  // Resets the buffer boundaries and the write pointer to the given |range|.
+  // Subsequent WriteByte(s) will write into |range|.
+  void Reset(ContiguousMemoryRange range);
+
+  // 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_);
+  }
+
+  uint8_t* write_ptr() const { return write_ptr_; }
+
+  uint64_t written() const {
+    return written_previously_ +
+           static_cast<uint64_t>(write_ptr_ - cur_range_.begin);
+  }
+
+ private:
+  ScatteredStreamWriter(const ScatteredStreamWriter&) = delete;
+  ScatteredStreamWriter& operator=(const ScatteredStreamWriter&) = delete;
+
+  void Extend();
+
+  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_
+// 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 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_
+
