Merge "Add testdata to Android.bp for perfetto_unittests."
diff --git a/.gitignore b/.gitignore
index ba585d6..821445d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,7 @@
 *.iml
 *.pyc
 *.swp
+/bazel-*
 /out*
 TAGS
 /node_modules/
diff --git a/Android.bp b/Android.bp
index fb804ca..a1595f9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -366,6 +366,7 @@
     "src/traced/probes/filesystem/range_tree.cc",
     "src/traced/probes/ftrace/atrace_hal_wrapper.cc",
     "src/traced/probes/ftrace/atrace_wrapper.cc",
+    "src/traced/probes/ftrace/compact_sched.cc",
     "src/traced/probes/ftrace/cpu_reader.cc",
     "src/traced/probes/ftrace/cpu_stats_parser.cc",
     "src/traced/probes/ftrace/event_info.cc",
@@ -1049,6 +1050,7 @@
     "src/traced/probes/filesystem/range_tree.cc",
     "src/traced/probes/ftrace/atrace_hal_wrapper.cc",
     "src/traced/probes/ftrace/atrace_wrapper.cc",
+    "src/traced/probes/ftrace/compact_sched.cc",
     "src/traced/probes/ftrace/cpu_reader.cc",
     "src/traced/probes/ftrace/cpu_stats_parser.cc",
     "src/traced/probes/ftrace/event_info.cc",
@@ -4394,7 +4396,7 @@
     "src/trace_processor/fuchsia_trace_tokenizer.cc",
     "src/trace_processor/fuchsia_trace_utils.cc",
     "src/trace_processor/fuchsia_trace_utils_unittest.cc",
-    "src/trace_processor/graphics_frame_event_parser.cc",
+    "src/trace_processor/graphics_event_parser.cc",
     "src/trace_processor/gzip_trace_parser.cc",
     "src/trace_processor/heap_profile_allocation_table.cc",
     "src/trace_processor/heap_profile_tracker.cc",
@@ -4472,6 +4474,7 @@
     "src/traced/probes/filesystem/range_tree_unittest.cc",
     "src/traced/probes/ftrace/atrace_hal_wrapper.cc",
     "src/traced/probes/ftrace/atrace_wrapper.cc",
+    "src/traced/probes/ftrace/compact_sched.cc",
     "src/traced/probes/ftrace/cpu_reader.cc",
     "src/traced/probes/ftrace/cpu_reader_unittest.cc",
     "src/traced/probes/ftrace/cpu_stats_parser.cc",
@@ -4747,7 +4750,7 @@
     "src/trace_processor/fuchsia_trace_parser.cc",
     "src/trace_processor/fuchsia_trace_tokenizer.cc",
     "src/trace_processor/fuchsia_trace_utils.cc",
-    "src/trace_processor/graphics_frame_event_parser.cc",
+    "src/trace_processor/graphics_event_parser.cc",
     "src/trace_processor/gzip_trace_parser.cc",
     "src/trace_processor/heap_profile_allocation_table.cc",
     "src/trace_processor/heap_profile_tracker.cc",
@@ -4944,7 +4947,7 @@
     "src/trace_processor/fuchsia_trace_parser.cc",
     "src/trace_processor/fuchsia_trace_tokenizer.cc",
     "src/trace_processor/fuchsia_trace_utils.cc",
-    "src/trace_processor/graphics_frame_event_parser.cc",
+    "src/trace_processor/graphics_event_parser.cc",
     "src/trace_processor/gzip_trace_parser.cc",
     "src/trace_processor/heap_profile_allocation_table.cc",
     "src/trace_processor/heap_profile_tracker.cc",
diff --git a/BUILD b/BUILD
index 5177498..c923a11 100644
--- a/BUILD
+++ b/BUILD
@@ -14,357 +14,573 @@
 #
 # This file is automatically generated by tools/gen_bazel. Do not edit.
 
-package(default_visibility = ["//visibility:public"])
+load("@perfetto_cfg//:perfetto_cfg.bzl", "PERFETTO_CONFIG")
+load(
+    "@perfetto//bazel:rules.bzl",
+    "perfetto_cc_binary",
+    "perfetto_cc_ipc_library",
+    "perfetto_cc_library",
+    "perfetto_cc_proto_library",
+    "perfetto_cc_protozero_library",
+    "perfetto_java_proto_library",
+    "perfetto_proto_library",
+    "perfetto_py_binary",
+    "perfetto_gensignature_internal_only",
+)
+
+package(default_visibility = ["//visibility:private"])
 
 licenses(["notice"])  # Apache 2.0
 
-exports_files(["LICENSE"])
+exports_files(["NOTICE"])
+# ##############################################################################
+# Internal targets
+# ##############################################################################
 
-# GN target: //src/trace_processor/metrics:gen_merged_sql_metrics
-genrule(
-    name = "gen_merged_sql_metrics",
+# GN target: //src/ipc/protoc_plugin:ipc_plugin
+perfetto_cc_binary(
+    name = "ipc_plugin",
     srcs = [
-        "src/trace_processor/metrics/android/android_batt.sql",
-        "src/trace_processor/metrics/android/android_cpu.sql",
-        "src/trace_processor/metrics/android/android_cpu_agg.sql",
-        "src/trace_processor/metrics/android/android_ion.sql",
-        "src/trace_processor/metrics/android/android_lmk.sql",
+        "src/ipc/protoc_plugin/ipc_plugin.cc",
+        ":include_perfetto_base_base",
+        ":include_perfetto_ext_base_base",
+        ":src_base_base",
+    ],
+    deps = [
+    ] + PERFETTO_CONFIG.deps.protoc_lib,
+)
+
+# GN target: //src/ipc:perfetto_ipc
+perfetto_cc_library(
+    name = "perfetto_ipc",
+    srcs = [
+        ":src_base_base",
+        ":src_base_unix_socket",
+        ":src_ipc_ipc",
+    ],
+    hdrs = [
+        ":include_perfetto_base_base",
+        ":include_perfetto_ext_base_base",
+        ":include_perfetto_ext_ipc_ipc",
+    ],
+    deps = [
+        ":protos_perfetto_ipc_wire_protocol",
+    ] + PERFETTO_CONFIG.deps.protobuf_lite,
+)
+
+# GN target: //src/protozero/protoc_plugin:protozero_plugin
+perfetto_cc_binary(
+    name = "protozero_plugin",
+    srcs = [
+        "src/protozero/protoc_plugin/protozero_plugin.cc",
+        ":include_perfetto_base_base",
+        ":include_perfetto_ext_base_base",
+        ":src_base_base",
+    ],
+    deps = [
+    ] + PERFETTO_CONFIG.deps.protoc_lib,
+)
+
+# GN target: //src/protozero:libprotozero
+perfetto_cc_library(
+    name = "libprotozero",
+    srcs = [
+        ":src_protozero_protozero",
+    ],
+    hdrs = [
+        ":include_perfetto_base_base",
+        ":include_perfetto_ext_base_base",
+        ":include_perfetto_protozero_protozero",
+    ],
+)
+
+# GN target: //:libperfetto
+perfetto_cc_library(
+    name = "libperfetto",
+    srcs = [
+        ":src_android_internal_headers",
+        ":src_android_internal_lazy_library_loader",
+        ":src_base_base",
+        ":src_base_unix_socket",
+        ":src_ipc_ipc",
+        ":src_protozero_protozero",
+        ":src_traced_probes_android_log_android_log",
+        ":src_traced_probes_data_source",
+        ":src_traced_probes_filesystem_filesystem",
+        ":src_traced_probes_ftrace_format_parser",
+        ":src_traced_probes_ftrace_ftrace",
+        ":src_traced_probes_metatrace_metatrace",
+        ":src_traced_probes_packages_list_packages_list",
+        ":src_traced_probes_power_power",
+        ":src_traced_probes_probes",
+        ":src_traced_probes_probes_src",
+        ":src_traced_probes_ps_ps",
+        ":src_traced_probes_sys_stats_sys_stats",
+        ":src_traced_service_service",
+        ":src_tracing_common",
+        ":src_tracing_consumer_api_deprecated",
+        ":src_tracing_ipc",
+        ":src_tracing_tracing",
+    ],
+    hdrs = [
+        ":include_perfetto_base_base",
+        ":include_perfetto_ext_base_base",
+        ":include_perfetto_ext_ipc_ipc",
+        ":include_perfetto_ext_traced_sys_stats_counters",
+        ":include_perfetto_ext_traced_traced",
+        ":include_perfetto_ext_tracing_core_core",
+        ":include_perfetto_ext_tracing_ipc_ipc",
+        ":include_perfetto_protozero_protozero",
+        ":include_perfetto_public_public",
+        ":include_perfetto_tracing_core_core",
+        ":include_perfetto_tracing_tracing",
+    ],
+    deps = [
+        ":protos_perfetto_common_lite",
+        ":protos_perfetto_common_zero",
+        ":protos_perfetto_config_android_lite",
+        ":protos_perfetto_config_android_zero",
+        ":protos_perfetto_config_ftrace_lite",
+        ":protos_perfetto_config_ftrace_zero",
+        ":protos_perfetto_config_gpu_lite",
+        ":protos_perfetto_config_gpu_zero",
+        ":protos_perfetto_config_inode_file_lite",
+        ":protos_perfetto_config_inode_file_zero",
+        ":protos_perfetto_config_lite",
+        ":protos_perfetto_config_power_lite",
+        ":protos_perfetto_config_power_zero",
+        ":protos_perfetto_config_process_stats_lite",
+        ":protos_perfetto_config_process_stats_zero",
+        ":protos_perfetto_config_profiling_lite",
+        ":protos_perfetto_config_profiling_zero",
+        ":protos_perfetto_config_sys_stats_lite",
+        ":protos_perfetto_config_sys_stats_zero",
+        ":protos_perfetto_config_zero",
+        ":protos_perfetto_ipc_ipc",
+        ":protos_perfetto_ipc_wire_protocol",
+        ":protos_perfetto_trace_android_zero",
+        ":protos_perfetto_trace_appended_data_zero",
+        ":protos_perfetto_trace_chrome_zero",
+        ":protos_perfetto_trace_filesystem_zero",
+        ":protos_perfetto_trace_ftrace_zero",
+        ":protos_perfetto_trace_gpu_zero",
+        ":protos_perfetto_trace_interned_data_zero",
+        ":protos_perfetto_trace_minimal_lite",
+        ":protos_perfetto_trace_minimal_zero",
+        ":protos_perfetto_trace_non_minimal_zero",
+        ":protos_perfetto_trace_perfetto_zero",
+        ":protos_perfetto_trace_power_zero",
+        ":protos_perfetto_trace_profiling_zero",
+        ":protos_perfetto_trace_ps_zero",
+        ":protos_perfetto_trace_sys_stats_zero",
+        ":protos_perfetto_trace_track_event_zero",
+        ":protos_perfetto_trace_trusted_lite",
+    ] + PERFETTO_CONFIG.deps.protobuf_lite,
+)
+
+# GN target: //include/perfetto/base:base
+filegroup(
+    name = "include_perfetto_base_base",
+    srcs = [
+        "include/perfetto/base/build_config.h",
+        "include/perfetto/base/compiler.h",
+        "include/perfetto/base/copyable_ptr.h",
+        "include/perfetto/base/export.h",
+        "include/perfetto/base/logging.h",
+        "include/perfetto/base/task_runner.h",
+        "include/perfetto/base/time.h",
+    ],
+)
+
+# GN target: //include/perfetto/ext/base:base
+filegroup(
+    name = "include_perfetto_ext_base_base",
+    srcs = [
+        "include/perfetto/ext/base/circular_queue.h",
+        "include/perfetto/ext/base/container_annotations.h",
+        "include/perfetto/ext/base/event_fd.h",
+        "include/perfetto/ext/base/file_utils.h",
+        "include/perfetto/ext/base/hash.h",
+        "include/perfetto/ext/base/lookup_set.h",
+        "include/perfetto/ext/base/metatrace.h",
+        "include/perfetto/ext/base/metatrace_events.h",
+        "include/perfetto/ext/base/no_destructor.h",
+        "include/perfetto/ext/base/optional.h",
+        "include/perfetto/ext/base/paged_memory.h",
+        "include/perfetto/ext/base/pipe.h",
+        "include/perfetto/ext/base/proc_utils.h",
+        "include/perfetto/ext/base/scoped_file.h",
+        "include/perfetto/ext/base/small_set.h",
+        "include/perfetto/ext/base/string_splitter.h",
+        "include/perfetto/ext/base/string_utils.h",
+        "include/perfetto/ext/base/string_view.h",
+        "include/perfetto/ext/base/string_writer.h",
+        "include/perfetto/ext/base/temp_file.h",
+        "include/perfetto/ext/base/thread_annotations.h",
+        "include/perfetto/ext/base/thread_checker.h",
+        "include/perfetto/ext/base/thread_task_runner.h",
+        "include/perfetto/ext/base/thread_utils.h",
+        "include/perfetto/ext/base/unix_socket.h",
+        "include/perfetto/ext/base/unix_task_runner.h",
+        "include/perfetto/ext/base/utils.h",
+        "include/perfetto/ext/base/uuid.h",
+        "include/perfetto/ext/base/waitable_event.h",
+        "include/perfetto/ext/base/watchdog.h",
+        "include/perfetto/ext/base/watchdog_noop.h",
+        "include/perfetto/ext/base/watchdog_posix.h",
+        "include/perfetto/ext/base/weak_ptr.h",
+    ],
+)
+
+# GN target: //include/perfetto/ext/ipc:ipc
+filegroup(
+    name = "include_perfetto_ext_ipc_ipc",
+    srcs = [
+        "include/perfetto/ext/ipc/async_result.h",
+        "include/perfetto/ext/ipc/basic_types.h",
+        "include/perfetto/ext/ipc/client.h",
+        "include/perfetto/ext/ipc/client_info.h",
+        "include/perfetto/ext/ipc/codegen_helpers.h",
+        "include/perfetto/ext/ipc/deferred.h",
+        "include/perfetto/ext/ipc/host.h",
+        "include/perfetto/ext/ipc/service.h",
+        "include/perfetto/ext/ipc/service_descriptor.h",
+        "include/perfetto/ext/ipc/service_proxy.h",
+    ],
+)
+
+# GN target: //include/perfetto/ext/traced:sys_stats_counters
+filegroup(
+    name = "include_perfetto_ext_traced_sys_stats_counters",
+    srcs = [
+        "include/perfetto/ext/traced/sys_stats_counters.h",
+    ],
+)
+
+# GN target: //include/perfetto/ext/traced:traced
+filegroup(
+    name = "include_perfetto_ext_traced_traced",
+    srcs = [
+        "include/perfetto/ext/traced/data_source_types.h",
+        "include/perfetto/ext/traced/traced.h",
+    ],
+)
+
+# GN target: //include/perfetto/ext/tracing/core:core
+filegroup(
+    name = "include_perfetto_ext_tracing_core_core",
+    srcs = [
+        "include/perfetto/ext/tracing/core/basic_types.h",
+        "include/perfetto/ext/tracing/core/buffer_exhausted_policy.h",
+        "include/perfetto/ext/tracing/core/commit_data_request.h",
+        "include/perfetto/ext/tracing/core/consumer.h",
+        "include/perfetto/ext/tracing/core/observable_events.h",
+        "include/perfetto/ext/tracing/core/producer.h",
+        "include/perfetto/ext/tracing/core/shared_memory.h",
+        "include/perfetto/ext/tracing/core/shared_memory_abi.h",
+        "include/perfetto/ext/tracing/core/shared_memory_arbiter.h",
+        "include/perfetto/ext/tracing/core/slice.h",
+        "include/perfetto/ext/tracing/core/sliced_protobuf_input_stream.h",
+        "include/perfetto/ext/tracing/core/startup_trace_writer.h",
+        "include/perfetto/ext/tracing/core/startup_trace_writer_registry.h",
+        "include/perfetto/ext/tracing/core/trace_packet.h",
+        "include/perfetto/ext/tracing/core/trace_stats.h",
+        "include/perfetto/ext/tracing/core/trace_writer.h",
+        "include/perfetto/ext/tracing/core/tracing_service.h",
+    ],
+)
+
+# GN target: //include/perfetto/ext/tracing/ipc:ipc
+filegroup(
+    name = "include_perfetto_ext_tracing_ipc_ipc",
+    srcs = [
+        "include/perfetto/ext/tracing/ipc/consumer_ipc_client.h",
+        "include/perfetto/ext/tracing/ipc/default_socket.h",
+        "include/perfetto/ext/tracing/ipc/producer_ipc_client.h",
+        "include/perfetto/ext/tracing/ipc/service_ipc_host.h",
+    ],
+)
+
+# GN target: //include/perfetto/protozero:protozero
+filegroup(
+    name = "include_perfetto_protozero_protozero",
+    srcs = [
+        "include/perfetto/protozero/contiguous_memory_range.h",
+        "include/perfetto/protozero/field.h",
+        "include/perfetto/protozero/message.h",
+        "include/perfetto/protozero/message_handle.h",
+        "include/perfetto/protozero/packed_repeated_fields.h",
+        "include/perfetto/protozero/proto_decoder.h",
+        "include/perfetto/protozero/proto_utils.h",
+        "include/perfetto/protozero/scattered_heap_buffer.h",
+        "include/perfetto/protozero/scattered_stream_null_delegate.h",
+        "include/perfetto/protozero/scattered_stream_writer.h",
+    ],
+)
+
+# GN target: //include/perfetto/public:public
+filegroup(
+    name = "include_perfetto_public_public",
+    srcs = [
+        "include/perfetto/public/consumer_api.h",
+    ],
+)
+
+# GN target: //include/perfetto/trace_processor:trace_processor
+filegroup(
+    name = "include_perfetto_trace_processor_trace_processor",
+    srcs = [
+        "include/perfetto/trace_processor/basic_types.h",
+        "include/perfetto/trace_processor/status.h",
+        "include/perfetto/trace_processor/trace_processor.h",
+    ],
+)
+
+# GN target: //include/perfetto/tracing/core:core
+filegroup(
+    name = "include_perfetto_tracing_core_core",
+    srcs = [
+        "include/perfetto/tracing/core/chrome_config.h",
+        "include/perfetto/tracing/core/data_source_config.h",
+        "include/perfetto/tracing/core/data_source_descriptor.h",
+        "include/perfetto/tracing/core/test_config.h",
+        "include/perfetto/tracing/core/trace_config.h",
+        "include/perfetto/tracing/core/tracing_service_state.h",
+    ],
+)
+
+# GN target: //include/perfetto/tracing:tracing
+filegroup(
+    name = "include_perfetto_tracing_tracing",
+    srcs = [
+        "include/perfetto/tracing/data_source.h",
+        "include/perfetto/tracing/internal/basic_types.h",
+        "include/perfetto/tracing/internal/data_source_internal.h",
+        "include/perfetto/tracing/internal/tracing_muxer.h",
+        "include/perfetto/tracing/internal/tracing_tls.h",
+        "include/perfetto/tracing/locked_handle.h",
+        "include/perfetto/tracing/platform.h",
+        "include/perfetto/tracing/trace_writer_base.h",
+        "include/perfetto/tracing/tracing.h",
+        "include/perfetto/tracing/tracing_backend.h",
+    ],
+)
+
+# GN target: //src/android_internal:headers
+filegroup(
+    name = "src_android_internal_headers",
+    srcs = [
+        "src/android_internal/atrace_hal.h",
+        "src/android_internal/dropbox_service.h",
+        "src/android_internal/health_hal.h",
+        "src/android_internal/incident_service.h",
+        "src/android_internal/power_stats_hal.h",
+    ],
+)
+
+# GN target: //src/android_internal:lazy_library_loader
+filegroup(
+    name = "src_android_internal_lazy_library_loader",
+    srcs = [
+        "src/android_internal/lazy_library_loader.cc",
+        "src/android_internal/lazy_library_loader.h",
+    ],
+)
+
+# GN target: //src/base:base
+filegroup(
+    name = "src_base_base",
+    srcs = [
+        "src/base/event_fd.cc",
+        "src/base/file_utils.cc",
+        "src/base/metatrace.cc",
+        "src/base/paged_memory.cc",
+        "src/base/pipe.cc",
+        "src/base/string_splitter.cc",
+        "src/base/string_utils.cc",
+        "src/base/string_view.cc",
+        "src/base/temp_file.cc",
+        "src/base/thread_checker.cc",
+        "src/base/thread_task_runner.cc",
+        "src/base/time.cc",
+        "src/base/unix_task_runner.cc",
+        "src/base/uuid.cc",
+        "src/base/virtual_destructors.cc",
+        "src/base/waitable_event.cc",
+        "src/base/watchdog_posix.cc",
+    ],
+)
+
+# GN target: //src/base:unix_socket
+filegroup(
+    name = "src_base_unix_socket",
+    srcs = [
+        "src/base/unix_socket.cc",
+    ],
+)
+
+# GN target: //src/ipc:ipc
+filegroup(
+    name = "src_ipc_ipc",
+    srcs = [
+        "src/ipc/buffered_frame_deserializer.cc",
+        "src/ipc/buffered_frame_deserializer.h",
+        "src/ipc/client_impl.cc",
+        "src/ipc/client_impl.h",
+        "src/ipc/deferred.cc",
+        "src/ipc/host_impl.cc",
+        "src/ipc/host_impl.h",
+        "src/ipc/service_proxy.cc",
+        "src/ipc/virtual_destructors.cc",
+    ],
+)
+
+# GN target: //src/perfetto_cmd:perfetto_cmd
+filegroup(
+    name = "src_perfetto_cmd_perfetto_cmd",
+    srcs = [
+        "src/perfetto_cmd/config.cc",
+        "src/perfetto_cmd/config.h",
+        "src/perfetto_cmd/packet_writer.cc",
+        "src/perfetto_cmd/packet_writer.h",
+        "src/perfetto_cmd/pbtxt_to_pb.cc",
+        "src/perfetto_cmd/pbtxt_to_pb.h",
+        "src/perfetto_cmd/perfetto_cmd.cc",
+        "src/perfetto_cmd/perfetto_cmd.h",
+        "src/perfetto_cmd/perfetto_config.descriptor.h",
+        "src/perfetto_cmd/rate_limiter.cc",
+        "src/perfetto_cmd/rate_limiter.h",
+    ],
+)
+
+# GN target: //src/perfetto_cmd:trigger_producer
+filegroup(
+    name = "src_perfetto_cmd_trigger_producer",
+    srcs = [
+        "src/perfetto_cmd/trigger_producer.cc",
+        "src/perfetto_cmd/trigger_producer.h",
+    ],
+)
+
+# GN target: //src/protozero:protozero
+filegroup(
+    name = "src_protozero_protozero",
+    srcs = [
+        "src/protozero/message.cc",
+        "src/protozero/message_handle.cc",
+        "src/protozero/proto_decoder.cc",
+        "src/protozero/scattered_heap_buffer.cc",
+        "src/protozero/scattered_stream_null_delegate.cc",
+        "src/protozero/scattered_stream_writer.cc",
+    ],
+)
+
+# GN target: //src/trace_processor/db:lib
+filegroup(
+    name = "src_trace_processor_db_lib",
+    srcs = [
+        "src/trace_processor/db/bit_vector.cc",
+        "src/trace_processor/db/bit_vector.h",
+        "src/trace_processor/db/column.cc",
+        "src/trace_processor/db/column.h",
+        "src/trace_processor/db/row_map.cc",
+        "src/trace_processor/db/row_map.h",
+        "src/trace_processor/db/sparse_vector.h",
+        "src/trace_processor/db/table.cc",
+        "src/trace_processor/db/table.h",
+        "src/trace_processor/db/typed_column.h",
+    ],
+)
+
+genrule(
+    name = "src_trace_processor_metrics_gen_merged_sql_metrics",
+    srcs = [
         "src/trace_processor/metrics/android/android_mem.sql",
-        "src/trace_processor/metrics/android/android_mem_unagg.sql",
-        "src/trace_processor/metrics/android/android_package_list.sql",
         "src/trace_processor/metrics/android/android_powrails.sql",
-        "src/trace_processor/metrics/android/android_process_growth.sql",
-        "src/trace_processor/metrics/android/android_startup.sql",
-        "src/trace_processor/metrics/android/android_startup_cpu.sql",
         "src/trace_processor/metrics/android/android_startup_launches.sql",
-        "src/trace_processor/metrics/android/android_task_state.sql",
-        "src/trace_processor/metrics/android/heap_profile_callsite_stats.sql",
+        "src/trace_processor/metrics/android/android_cpu_agg.sql",
+        "src/trace_processor/metrics/android/upid_span_view.sql",
+        "src/trace_processor/metrics/android/android_mem_unagg.sql",
+        "src/trace_processor/metrics/android/android_process_growth.sql",
         "src/trace_processor/metrics/android/mem_stats_priority_breakdown.sql",
-        "src/trace_processor/metrics/android/process_mem.sql",
+        "src/trace_processor/metrics/android/android_batt.sql",
+        "src/trace_processor/metrics/android/android_startup.sql",
+        "src/trace_processor/metrics/trace_metadata.sql",
+        "src/trace_processor/metrics/android/android_ion.sql",
+        "src/trace_processor/metrics/android/android_startup_cpu.sql",
+        "src/trace_processor/metrics/android/android_package_list.sql",
+        "src/trace_processor/metrics/android/android_cpu.sql",
         "src/trace_processor/metrics/android/process_unagg_mem_view.sql",
         "src/trace_processor/metrics/android/span_view_stats.sql",
-        "src/trace_processor/metrics/android/upid_span_view.sql",
-        "src/trace_processor/metrics/trace_metadata.sql",
+        "src/trace_processor/metrics/android/heap_profile_callsite_stats.sql",
+        "src/trace_processor/metrics/android/android_task_state.sql",
+        "src/trace_processor/metrics/android/process_mem.sql",
+        "src/trace_processor/metrics/android/android_lmk.sql",
     ],
     outs = [
         "src/trace_processor/metrics/sql_metrics.h",
     ],
     cmd = "$(location gen_merged_sql_metrics_py) --cpp_out=$@ $(SRCS)",
     tools = [
-        "gen_merged_sql_metrics_py",
+        ":gen_merged_sql_metrics_py",
     ],
 )
 
-# GN target: //tools/trace_to_text:libpprofbuilder
-cc_library(
-    name = "libpprofbuilder",
+# GN target: //src/trace_processor/metrics:lib
+filegroup(
+    name = "src_trace_processor_metrics_lib",
     srcs = [
-        "src/base/event_fd.cc",
-        "src/base/file_utils.cc",
-        "src/base/metatrace.cc",
-        "src/base/paged_memory.cc",
-        "src/base/pipe.cc",
-        "src/base/string_splitter.cc",
-        "src/base/string_utils.cc",
-        "src/base/string_view.cc",
-        "src/base/temp_file.cc",
-        "src/base/thread_checker.cc",
-        "src/base/thread_task_runner.cc",
-        "src/base/time.cc",
-        "src/base/unix_task_runner.cc",
-        "src/base/uuid.cc",
-        "src/base/virtual_destructors.cc",
-        "src/base/waitable_event.cc",
-        "src/base/watchdog_posix.cc",
-        "src/protozero/message.cc",
-        "src/protozero/message_handle.cc",
-        "src/protozero/proto_decoder.cc",
-        "src/protozero/scattered_heap_buffer.cc",
-        "src/protozero/scattered_stream_null_delegate.cc",
-        "src/protozero/scattered_stream_writer.cc",
-        "tools/trace_to_text/pprof_builder.cc",
-        "tools/trace_to_text/profile_visitor.cc",
-        "tools/trace_to_text/profile_visitor.h",
-        "tools/trace_to_text/symbolizer.cc",
-        "tools/trace_to_text/trace_symbol_table.cc",
-        "tools/trace_to_text/trace_symbol_table.h",
-        "tools/trace_to_text/utils.cc",
-        "tools/trace_to_text/utils.h",
-    ],
-    hdrs = [
-        "include/perfetto/base/build_config.h",
-        "include/perfetto/base/build_configs/bazel/perfetto_build_flags.h",
-        "include/perfetto/base/compiler.h",
-        "include/perfetto/base/copyable_ptr.h",
-        "include/perfetto/base/export.h",
-        "include/perfetto/base/logging.h",
-        "include/perfetto/base/task_runner.h",
-        "include/perfetto/base/time.h",
-        "include/perfetto/ext/base/circular_queue.h",
-        "include/perfetto/ext/base/container_annotations.h",
-        "include/perfetto/ext/base/event_fd.h",
-        "include/perfetto/ext/base/file_utils.h",
-        "include/perfetto/ext/base/hash.h",
-        "include/perfetto/ext/base/lookup_set.h",
-        "include/perfetto/ext/base/metatrace.h",
-        "include/perfetto/ext/base/metatrace_events.h",
-        "include/perfetto/ext/base/no_destructor.h",
-        "include/perfetto/ext/base/optional.h",
-        "include/perfetto/ext/base/paged_memory.h",
-        "include/perfetto/ext/base/pipe.h",
-        "include/perfetto/ext/base/proc_utils.h",
-        "include/perfetto/ext/base/scoped_file.h",
-        "include/perfetto/ext/base/small_set.h",
-        "include/perfetto/ext/base/string_splitter.h",
-        "include/perfetto/ext/base/string_utils.h",
-        "include/perfetto/ext/base/string_view.h",
-        "include/perfetto/ext/base/string_writer.h",
-        "include/perfetto/ext/base/temp_file.h",
-        "include/perfetto/ext/base/thread_annotations.h",
-        "include/perfetto/ext/base/thread_checker.h",
-        "include/perfetto/ext/base/thread_task_runner.h",
-        "include/perfetto/ext/base/thread_utils.h",
-        "include/perfetto/ext/base/unix_socket.h",
-        "include/perfetto/ext/base/unix_task_runner.h",
-        "include/perfetto/ext/base/utils.h",
-        "include/perfetto/ext/base/uuid.h",
-        "include/perfetto/ext/base/waitable_event.h",
-        "include/perfetto/ext/base/watchdog.h",
-        "include/perfetto/ext/base/watchdog_noop.h",
-        "include/perfetto/ext/base/watchdog_posix.h",
-        "include/perfetto/ext/base/weak_ptr.h",
-        "include/perfetto/ext/traced/sys_stats_counters.h",
-        "include/perfetto/protozero/contiguous_memory_range.h",
-        "include/perfetto/protozero/field.h",
-        "include/perfetto/protozero/message.h",
-        "include/perfetto/protozero/message_handle.h",
-        "include/perfetto/protozero/packed_repeated_fields.h",
-        "include/perfetto/protozero/proto_decoder.h",
-        "include/perfetto/protozero/proto_utils.h",
-        "include/perfetto/protozero/scattered_heap_buffer.h",
-        "include/perfetto/protozero/scattered_stream_null_delegate.h",
-        "include/perfetto/protozero/scattered_stream_writer.h",
-        "tools/trace_to_text/pprof_builder.h",
-        "tools/trace_to_text/symbolizer.h",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:common_cc_proto",
-        "//third_party/perfetto/protos:common_zero_cc_proto",
-        "//third_party/perfetto/protos:config_android_cc_proto",
-        "//third_party/perfetto/protos:config_android_zero_cc_proto",
-        "//third_party/perfetto/protos:config_cc_proto",
-        "//third_party/perfetto/protos:config_ftrace_cc_proto",
-        "//third_party/perfetto/protos:config_ftrace_zero_cc_proto",
-        "//third_party/perfetto/protos:config_gpu_cc_proto",
-        "//third_party/perfetto/protos:config_gpu_zero_cc_proto",
-        "//third_party/perfetto/protos:config_inode_file_cc_proto",
-        "//third_party/perfetto/protos:config_inode_file_zero_cc_proto",
-        "//third_party/perfetto/protos:config_power_cc_proto",
-        "//third_party/perfetto/protos:config_power_zero_cc_proto",
-        "//third_party/perfetto/protos:config_process_stats_cc_proto",
-        "//third_party/perfetto/protos:config_process_stats_zero_cc_proto",
-        "//third_party/perfetto/protos:config_profiling_cc_proto",
-        "//third_party/perfetto/protos:config_profiling_zero_cc_proto",
-        "//third_party/perfetto/protos:config_sys_stats_cc_proto",
-        "//third_party/perfetto/protos:config_sys_stats_zero_cc_proto",
-        "//third_party/perfetto/protos:config_zero_cc_proto",
-        "//third_party/perfetto/protos:protos_third_party_pprof_cc_proto",
-        "//third_party/perfetto/protos:trace_android_cc_proto",
-        "//third_party/perfetto/protos:trace_android_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_appended_data_cc_proto",
-        "//third_party/perfetto/protos:trace_appended_data_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_chrome_cc_proto",
-        "//third_party/perfetto/protos:trace_chrome_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_filesystem_cc_proto",
-        "//third_party/perfetto/protos:trace_filesystem_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_ftrace_cc_proto",
-        "//third_party/perfetto/protos:trace_ftrace_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_gpu_cc_proto",
-        "//third_party/perfetto/protos:trace_gpu_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_interned_data_cc_proto",
-        "//third_party/perfetto/protos:trace_interned_data_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_minimal_cc_proto",
-        "//third_party/perfetto/protos:trace_minimal_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_non_minimal_cc_proto",
-        "//third_party/perfetto/protos:trace_non_minimal_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_perfetto_cc_proto",
-        "//third_party/perfetto/protos:trace_perfetto_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_power_cc_proto",
-        "//third_party/perfetto/protos:trace_power_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_profiling_cc_proto",
-        "//third_party/perfetto/protos:trace_profiling_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_ps_cc_proto",
-        "//third_party/perfetto/protos:trace_ps_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_sys_stats_cc_proto",
-        "//third_party/perfetto/protos:trace_sys_stats_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_track_event_cc_proto",
-        "//third_party/perfetto/protos:trace_track_event_zero_cc_proto",
+        "src/trace_processor/metrics/descriptors.cc",
+        "src/trace_processor/metrics/descriptors.h",
+        "src/trace_processor/metrics/metrics.cc",
+        "src/trace_processor/metrics/metrics.descriptor.h",
+        "src/trace_processor/metrics/metrics.h",
     ],
 )
 
-# GN target: //src/protozero:libprotozero
-cc_library(
-    name = "libprotozero",
+# GN target: //src/trace_processor/sqlite:sqlite
+filegroup(
+    name = "src_trace_processor_sqlite_sqlite",
     srcs = [
-        "src/protozero/message.cc",
-        "src/protozero/message_handle.cc",
-        "src/protozero/proto_decoder.cc",
-        "src/protozero/scattered_heap_buffer.cc",
-        "src/protozero/scattered_stream_null_delegate.cc",
-        "src/protozero/scattered_stream_writer.cc",
-    ],
-    hdrs = [
-        "include/perfetto/base/build_config.h",
-        "include/perfetto/base/build_configs/bazel/perfetto_build_flags.h",
-        "include/perfetto/base/compiler.h",
-        "include/perfetto/base/copyable_ptr.h",
-        "include/perfetto/base/export.h",
-        "include/perfetto/base/logging.h",
-        "include/perfetto/base/task_runner.h",
-        "include/perfetto/base/time.h",
-        "include/perfetto/ext/base/circular_queue.h",
-        "include/perfetto/ext/base/container_annotations.h",
-        "include/perfetto/ext/base/event_fd.h",
-        "include/perfetto/ext/base/file_utils.h",
-        "include/perfetto/ext/base/hash.h",
-        "include/perfetto/ext/base/lookup_set.h",
-        "include/perfetto/ext/base/metatrace.h",
-        "include/perfetto/ext/base/metatrace_events.h",
-        "include/perfetto/ext/base/no_destructor.h",
-        "include/perfetto/ext/base/optional.h",
-        "include/perfetto/ext/base/paged_memory.h",
-        "include/perfetto/ext/base/pipe.h",
-        "include/perfetto/ext/base/proc_utils.h",
-        "include/perfetto/ext/base/scoped_file.h",
-        "include/perfetto/ext/base/small_set.h",
-        "include/perfetto/ext/base/string_splitter.h",
-        "include/perfetto/ext/base/string_utils.h",
-        "include/perfetto/ext/base/string_view.h",
-        "include/perfetto/ext/base/string_writer.h",
-        "include/perfetto/ext/base/temp_file.h",
-        "include/perfetto/ext/base/thread_annotations.h",
-        "include/perfetto/ext/base/thread_checker.h",
-        "include/perfetto/ext/base/thread_task_runner.h",
-        "include/perfetto/ext/base/thread_utils.h",
-        "include/perfetto/ext/base/unix_socket.h",
-        "include/perfetto/ext/base/unix_task_runner.h",
-        "include/perfetto/ext/base/utils.h",
-        "include/perfetto/ext/base/uuid.h",
-        "include/perfetto/ext/base/waitable_event.h",
-        "include/perfetto/ext/base/watchdog.h",
-        "include/perfetto/ext/base/watchdog_noop.h",
-        "include/perfetto/ext/base/watchdog_posix.h",
-        "include/perfetto/ext/base/weak_ptr.h",
-        "include/perfetto/protozero/contiguous_memory_range.h",
-        "include/perfetto/protozero/field.h",
-        "include/perfetto/protozero/message.h",
-        "include/perfetto/protozero/message_handle.h",
-        "include/perfetto/protozero/packed_repeated_fields.h",
-        "include/perfetto/protozero/proto_decoder.h",
-        "include/perfetto/protozero/proto_utils.h",
-        "include/perfetto/protozero/scattered_heap_buffer.h",
-        "include/perfetto/protozero/scattered_stream_null_delegate.h",
-        "include/perfetto/protozero/scattered_stream_writer.h",
+        "src/trace_processor/sqlite/db_sqlite_table.cc",
+        "src/trace_processor/sqlite/db_sqlite_table.h",
+        "src/trace_processor/sqlite/query_constraints.cc",
+        "src/trace_processor/sqlite/query_constraints.h",
+        "src/trace_processor/sqlite/scoped_db.h",
+        "src/trace_processor/sqlite/sqlite3_str_split.cc",
+        "src/trace_processor/sqlite/sqlite3_str_split.h",
+        "src/trace_processor/sqlite/sqlite_table.cc",
+        "src/trace_processor/sqlite/sqlite_table.h",
+        "src/trace_processor/sqlite/sqlite_utils.h",
     ],
 )
 
-# GN target: //src/protozero/protoc_plugin:protozero_plugin
-cc_binary(
-    name = "src_protozero_protoc_plugin_protozero_plugin",
+# GN target: //src/trace_processor/tables:tables
+filegroup(
+    name = "src_trace_processor_tables_tables",
     srcs = [
-        "include/perfetto/base/build_config.h",
-        "include/perfetto/base/build_configs/bazel/perfetto_build_flags.h",
-        "include/perfetto/base/compiler.h",
-        "include/perfetto/base/copyable_ptr.h",
-        "include/perfetto/base/export.h",
-        "include/perfetto/base/logging.h",
-        "include/perfetto/base/task_runner.h",
-        "include/perfetto/base/time.h",
-        "include/perfetto/ext/base/circular_queue.h",
-        "include/perfetto/ext/base/container_annotations.h",
-        "include/perfetto/ext/base/event_fd.h",
-        "include/perfetto/ext/base/file_utils.h",
-        "include/perfetto/ext/base/hash.h",
-        "include/perfetto/ext/base/lookup_set.h",
-        "include/perfetto/ext/base/metatrace.h",
-        "include/perfetto/ext/base/metatrace_events.h",
-        "include/perfetto/ext/base/no_destructor.h",
-        "include/perfetto/ext/base/optional.h",
-        "include/perfetto/ext/base/paged_memory.h",
-        "include/perfetto/ext/base/pipe.h",
-        "include/perfetto/ext/base/proc_utils.h",
-        "include/perfetto/ext/base/scoped_file.h",
-        "include/perfetto/ext/base/small_set.h",
-        "include/perfetto/ext/base/string_splitter.h",
-        "include/perfetto/ext/base/string_utils.h",
-        "include/perfetto/ext/base/string_view.h",
-        "include/perfetto/ext/base/string_writer.h",
-        "include/perfetto/ext/base/temp_file.h",
-        "include/perfetto/ext/base/thread_annotations.h",
-        "include/perfetto/ext/base/thread_checker.h",
-        "include/perfetto/ext/base/thread_task_runner.h",
-        "include/perfetto/ext/base/thread_utils.h",
-        "include/perfetto/ext/base/unix_socket.h",
-        "include/perfetto/ext/base/unix_task_runner.h",
-        "include/perfetto/ext/base/utils.h",
-        "include/perfetto/ext/base/uuid.h",
-        "include/perfetto/ext/base/waitable_event.h",
-        "include/perfetto/ext/base/watchdog.h",
-        "include/perfetto/ext/base/watchdog_noop.h",
-        "include/perfetto/ext/base/watchdog_posix.h",
-        "include/perfetto/ext/base/weak_ptr.h",
-        "src/base/event_fd.cc",
-        "src/base/file_utils.cc",
-        "src/base/metatrace.cc",
-        "src/base/paged_memory.cc",
-        "src/base/pipe.cc",
-        "src/base/string_splitter.cc",
-        "src/base/string_utils.cc",
-        "src/base/string_view.cc",
-        "src/base/temp_file.cc",
-        "src/base/thread_checker.cc",
-        "src/base/thread_task_runner.cc",
-        "src/base/time.cc",
-        "src/base/unix_task_runner.cc",
-        "src/base/uuid.cc",
-        "src/base/virtual_destructors.cc",
-        "src/base/waitable_event.cc",
-        "src/base/watchdog_posix.cc",
-        "src/protozero/protoc_plugin/protozero_plugin.cc",
-    ],
-    deps = [
-        "//third_party/protobuf:libprotoc_legacy",
-        "//third_party/protobuf:protobuf_legacy",
+        "src/trace_processor/tables/macros.h",
+        "src/trace_processor/tables/macros_internal.h",
+        "src/trace_processor/tables/profiler_tables.h",
+        "src/trace_processor/tables/slice_tables.h",
+        "src/trace_processor/tables/track_tables.h",
     ],
 )
 
-# GN target: //src/trace_processor:trace_processor
-cc_library(
-    name = "trace_processor",
+# GN target: //src/trace_processor:common
+filegroup(
+    name = "src_trace_processor_common",
     srcs = [
-        "src/base/event_fd.cc",
-        "src/base/file_utils.cc",
-        "src/base/metatrace.cc",
-        "src/base/paged_memory.cc",
-        "src/base/pipe.cc",
-        "src/base/string_splitter.cc",
-        "src/base/string_utils.cc",
-        "src/base/string_view.cc",
-        "src/base/temp_file.cc",
-        "src/base/thread_checker.cc",
-        "src/base/thread_task_runner.cc",
-        "src/base/time.cc",
-        "src/base/unix_task_runner.cc",
-        "src/base/uuid.cc",
-        "src/base/virtual_destructors.cc",
-        "src/base/waitable_event.cc",
-        "src/base/watchdog_posix.cc",
-        "src/protozero/message.cc",
-        "src/protozero/message_handle.cc",
-        "src/protozero/proto_decoder.cc",
-        "src/protozero/scattered_heap_buffer.cc",
-        "src/protozero/scattered_stream_null_delegate.cc",
-        "src/protozero/scattered_stream_writer.cc",
+        "src/trace_processor/null_term_string_view.h",
+        "src/trace_processor/string_pool.cc",
+        "src/trace_processor/string_pool.h",
+    ],
+)
+
+# GN target: //src/trace_processor:lib
+filegroup(
+    name = "src_trace_processor_lib",
+    srcs = [
         "src/trace_processor/android_logs_table.cc",
         "src/trace_processor/android_logs_table.h",
         "src/trace_processor/args_table.cc",
@@ -380,16 +596,6 @@
         "src/trace_processor/counter_values_table.h",
         "src/trace_processor/cpu_profile_stack_sample_table.cc",
         "src/trace_processor/cpu_profile_stack_sample_table.h",
-        "src/trace_processor/db/bit_vector.cc",
-        "src/trace_processor/db/bit_vector.h",
-        "src/trace_processor/db/column.cc",
-        "src/trace_processor/db/column.h",
-        "src/trace_processor/db/row_map.cc",
-        "src/trace_processor/db/row_map.h",
-        "src/trace_processor/db/sparse_vector.h",
-        "src/trace_processor/db/table.cc",
-        "src/trace_processor/db/table.h",
-        "src/trace_processor/db/typed_column.h",
         "src/trace_processor/event_tracker.cc",
         "src/trace_processor/event_tracker.h",
         "src/trace_processor/export_json.cc",
@@ -410,8 +616,8 @@
         "src/trace_processor/fuchsia_trace_tokenizer.h",
         "src/trace_processor/fuchsia_trace_utils.cc",
         "src/trace_processor/fuchsia_trace_utils.h",
-        "src/trace_processor/graphics_frame_event_parser.cc",
-        "src/trace_processor/graphics_frame_event_parser.h",
+        "src/trace_processor/graphics_event_parser.cc",
+        "src/trace_processor/graphics_event_parser.h",
         "src/trace_processor/gzip_trace_parser.cc",
         "src/trace_processor/gzip_trace_parser.h",
         "src/trace_processor/heap_profile_allocation_table.cc",
@@ -429,13 +635,6 @@
         "src/trace_processor/metadata.h",
         "src/trace_processor/metadata_table.cc",
         "src/trace_processor/metadata_table.h",
-        "src/trace_processor/metrics/descriptors.cc",
-        "src/trace_processor/metrics/descriptors.h",
-        "src/trace_processor/metrics/metrics.cc",
-        "src/trace_processor/metrics/metrics.descriptor.h",
-        "src/trace_processor/metrics/metrics.h",
-        "src/trace_processor/metrics/sql_metrics.h",
-        "src/trace_processor/null_term_string_view.h",
         "src/trace_processor/process_table.cc",
         "src/trace_processor/process_table.h",
         "src/trace_processor/process_tracker.cc",
@@ -459,16 +658,6 @@
         "src/trace_processor/span_join_operator_table.h",
         "src/trace_processor/sql_stats_table.cc",
         "src/trace_processor/sql_stats_table.h",
-        "src/trace_processor/sqlite/db_sqlite_table.cc",
-        "src/trace_processor/sqlite/db_sqlite_table.h",
-        "src/trace_processor/sqlite/query_constraints.cc",
-        "src/trace_processor/sqlite/query_constraints.h",
-        "src/trace_processor/sqlite/scoped_db.h",
-        "src/trace_processor/sqlite/sqlite3_str_split.cc",
-        "src/trace_processor/sqlite/sqlite3_str_split.h",
-        "src/trace_processor/sqlite/sqlite_table.cc",
-        "src/trace_processor/sqlite/sqlite_table.h",
-        "src/trace_processor/sqlite/sqlite_utils.h",
         "src/trace_processor/stack_profile_callsite_table.cc",
         "src/trace_processor/stack_profile_callsite_table.h",
         "src/trace_processor/stack_profile_frame_table.cc",
@@ -486,8 +675,6 @@
         "src/trace_processor/storage_schema.h",
         "src/trace_processor/storage_table.cc",
         "src/trace_processor/storage_table.h",
-        "src/trace_processor/string_pool.cc",
-        "src/trace_processor/string_pool.h",
         "src/trace_processor/syscall_tracker.cc",
         "src/trace_processor/syscall_tracker.h",
         "src/trace_processor/syscalls_aarch32.h",
@@ -498,10 +685,6 @@
         "src/trace_processor/systrace_parser.h",
         "src/trace_processor/systrace_trace_parser.cc",
         "src/trace_processor/systrace_trace_parser.h",
-        "src/trace_processor/tables/macros.h",
-        "src/trace_processor/tables/macros_internal.h",
-        "src/trace_processor/tables/slice_tables.h",
-        "src/trace_processor/tables/track_tables.h",
         "src/trace_processor/thread_table.cc",
         "src/trace_processor/thread_table.h",
         "src/trace_processor/trace_blob_view.h",
@@ -522,710 +705,1683 @@
         "src/trace_processor/window_operator_table.cc",
         "src/trace_processor/window_operator_table.h",
     ],
-    hdrs = [
-        "include/perfetto/base/build_config.h",
-        "include/perfetto/base/build_configs/bazel/perfetto_build_flags.h",
-        "include/perfetto/base/compiler.h",
-        "include/perfetto/base/copyable_ptr.h",
-        "include/perfetto/base/export.h",
-        "include/perfetto/base/logging.h",
-        "include/perfetto/base/task_runner.h",
-        "include/perfetto/base/time.h",
-        "include/perfetto/ext/base/circular_queue.h",
-        "include/perfetto/ext/base/container_annotations.h",
-        "include/perfetto/ext/base/event_fd.h",
-        "include/perfetto/ext/base/file_utils.h",
-        "include/perfetto/ext/base/hash.h",
-        "include/perfetto/ext/base/lookup_set.h",
-        "include/perfetto/ext/base/metatrace.h",
-        "include/perfetto/ext/base/metatrace_events.h",
-        "include/perfetto/ext/base/no_destructor.h",
-        "include/perfetto/ext/base/optional.h",
-        "include/perfetto/ext/base/paged_memory.h",
-        "include/perfetto/ext/base/pipe.h",
-        "include/perfetto/ext/base/proc_utils.h",
-        "include/perfetto/ext/base/scoped_file.h",
-        "include/perfetto/ext/base/small_set.h",
-        "include/perfetto/ext/base/string_splitter.h",
-        "include/perfetto/ext/base/string_utils.h",
-        "include/perfetto/ext/base/string_view.h",
-        "include/perfetto/ext/base/string_writer.h",
-        "include/perfetto/ext/base/temp_file.h",
-        "include/perfetto/ext/base/thread_annotations.h",
-        "include/perfetto/ext/base/thread_checker.h",
-        "include/perfetto/ext/base/thread_task_runner.h",
-        "include/perfetto/ext/base/thread_utils.h",
-        "include/perfetto/ext/base/unix_socket.h",
-        "include/perfetto/ext/base/unix_task_runner.h",
-        "include/perfetto/ext/base/utils.h",
-        "include/perfetto/ext/base/uuid.h",
-        "include/perfetto/ext/base/waitable_event.h",
-        "include/perfetto/ext/base/watchdog.h",
-        "include/perfetto/ext/base/watchdog_noop.h",
-        "include/perfetto/ext/base/watchdog_posix.h",
-        "include/perfetto/ext/base/weak_ptr.h",
-        "include/perfetto/ext/traced/sys_stats_counters.h",
-        "include/perfetto/protozero/contiguous_memory_range.h",
-        "include/perfetto/protozero/field.h",
-        "include/perfetto/protozero/message.h",
-        "include/perfetto/protozero/message_handle.h",
-        "include/perfetto/protozero/packed_repeated_fields.h",
-        "include/perfetto/protozero/proto_decoder.h",
-        "include/perfetto/protozero/proto_utils.h",
-        "include/perfetto/protozero/scattered_heap_buffer.h",
-        "include/perfetto/protozero/scattered_stream_null_delegate.h",
-        "include/perfetto/protozero/scattered_stream_writer.h",
-        "include/perfetto/trace_processor/basic_types.h",
-        "include/perfetto/trace_processor/status.h",
-        "include/perfetto/trace_processor/trace_processor.h",
-    ],
-    deps = [
-        "//third_party/perfetto:gen_merged_sql_metrics",
-        "//third_party/perfetto/google:jsoncpp",
-        "//third_party/perfetto/protos:common_zero_cc_proto",
-        "//third_party/perfetto/protos:config_android_zero_cc_proto",
-        "//third_party/perfetto/protos:config_ftrace_zero_cc_proto",
-        "//third_party/perfetto/protos:config_gpu_zero_cc_proto",
-        "//third_party/perfetto/protos:config_inode_file_zero_cc_proto",
-        "//third_party/perfetto/protos:config_power_zero_cc_proto",
-        "//third_party/perfetto/protos:config_process_stats_zero_cc_proto",
-        "//third_party/perfetto/protos:config_profiling_zero_cc_proto",
-        "//third_party/perfetto/protos:config_sys_stats_zero_cc_proto",
-        "//third_party/perfetto/protos:config_zero_cc_proto",
-        "//third_party/perfetto/protos:metrics_android_zero_cc_proto",
-        "//third_party/perfetto/protos:metrics_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_android_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_appended_data_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_chrome_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_filesystem_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_ftrace_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_gpu_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_interned_data_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_minimal_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_non_minimal_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_perfetto_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_power_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_processor_metrics_impl_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_profiling_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_ps_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_sys_stats_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_track_event_zero_cc_proto",
-        "//third_party/sqlite",
-        "//third_party/sqlite:sqlite_ext_percentile",
-        "//third_party/zlib:zlibsystem",
-    ],
 )
 
-# GN target: //src/trace_processor:trace_processor_shell
-cc_binary(
-    name = "trace_processor_shell",
+# GN target: //src/traced/probes/android_log:android_log
+filegroup(
+    name = "src_traced_probes_android_log_android_log",
     srcs = [
-        "include/perfetto/base/build_config.h",
-        "include/perfetto/base/build_configs/bazel/perfetto_build_flags.h",
-        "include/perfetto/base/compiler.h",
-        "include/perfetto/base/copyable_ptr.h",
-        "include/perfetto/base/export.h",
-        "include/perfetto/base/logging.h",
-        "include/perfetto/base/task_runner.h",
-        "include/perfetto/base/time.h",
-        "include/perfetto/ext/base/circular_queue.h",
-        "include/perfetto/ext/base/container_annotations.h",
-        "include/perfetto/ext/base/event_fd.h",
-        "include/perfetto/ext/base/file_utils.h",
-        "include/perfetto/ext/base/hash.h",
-        "include/perfetto/ext/base/lookup_set.h",
-        "include/perfetto/ext/base/metatrace.h",
-        "include/perfetto/ext/base/metatrace_events.h",
-        "include/perfetto/ext/base/no_destructor.h",
-        "include/perfetto/ext/base/optional.h",
-        "include/perfetto/ext/base/paged_memory.h",
-        "include/perfetto/ext/base/pipe.h",
-        "include/perfetto/ext/base/proc_utils.h",
-        "include/perfetto/ext/base/scoped_file.h",
-        "include/perfetto/ext/base/small_set.h",
-        "include/perfetto/ext/base/string_splitter.h",
-        "include/perfetto/ext/base/string_utils.h",
-        "include/perfetto/ext/base/string_view.h",
-        "include/perfetto/ext/base/string_writer.h",
-        "include/perfetto/ext/base/temp_file.h",
-        "include/perfetto/ext/base/thread_annotations.h",
-        "include/perfetto/ext/base/thread_checker.h",
-        "include/perfetto/ext/base/thread_task_runner.h",
-        "include/perfetto/ext/base/thread_utils.h",
-        "include/perfetto/ext/base/unix_socket.h",
-        "include/perfetto/ext/base/unix_task_runner.h",
-        "include/perfetto/ext/base/utils.h",
-        "include/perfetto/ext/base/uuid.h",
-        "include/perfetto/ext/base/waitable_event.h",
-        "include/perfetto/ext/base/watchdog.h",
-        "include/perfetto/ext/base/watchdog_noop.h",
-        "include/perfetto/ext/base/watchdog_posix.h",
-        "include/perfetto/ext/base/weak_ptr.h",
-        "include/perfetto/ext/traced/sys_stats_counters.h",
-        "include/perfetto/protozero/contiguous_memory_range.h",
-        "include/perfetto/protozero/field.h",
-        "include/perfetto/protozero/message.h",
-        "include/perfetto/protozero/message_handle.h",
-        "include/perfetto/protozero/packed_repeated_fields.h",
-        "include/perfetto/protozero/proto_decoder.h",
-        "include/perfetto/protozero/proto_utils.h",
-        "include/perfetto/protozero/scattered_heap_buffer.h",
-        "include/perfetto/protozero/scattered_stream_null_delegate.h",
-        "include/perfetto/protozero/scattered_stream_writer.h",
-        "include/perfetto/trace_processor/basic_types.h",
-        "include/perfetto/trace_processor/status.h",
-        "include/perfetto/trace_processor/trace_processor.h",
-        "src/base/event_fd.cc",
-        "src/base/file_utils.cc",
-        "src/base/metatrace.cc",
-        "src/base/paged_memory.cc",
-        "src/base/pipe.cc",
-        "src/base/string_splitter.cc",
-        "src/base/string_utils.cc",
-        "src/base/string_view.cc",
-        "src/base/temp_file.cc",
-        "src/base/thread_checker.cc",
-        "src/base/thread_task_runner.cc",
-        "src/base/time.cc",
-        "src/base/unix_task_runner.cc",
-        "src/base/uuid.cc",
-        "src/base/virtual_destructors.cc",
-        "src/base/waitable_event.cc",
-        "src/base/watchdog_posix.cc",
-        "src/protozero/message.cc",
-        "src/protozero/message_handle.cc",
-        "src/protozero/proto_decoder.cc",
-        "src/protozero/scattered_heap_buffer.cc",
-        "src/protozero/scattered_stream_null_delegate.cc",
-        "src/protozero/scattered_stream_writer.cc",
-        "src/trace_processor/android_logs_table.cc",
-        "src/trace_processor/android_logs_table.h",
-        "src/trace_processor/args_table.cc",
-        "src/trace_processor/args_table.h",
-        "src/trace_processor/args_tracker.cc",
-        "src/trace_processor/args_tracker.h",
-        "src/trace_processor/chunked_trace_reader.h",
-        "src/trace_processor/clock_tracker.cc",
-        "src/trace_processor/clock_tracker.h",
-        "src/trace_processor/counter_definitions_table.cc",
-        "src/trace_processor/counter_definitions_table.h",
-        "src/trace_processor/counter_values_table.cc",
-        "src/trace_processor/counter_values_table.h",
-        "src/trace_processor/cpu_profile_stack_sample_table.cc",
-        "src/trace_processor/cpu_profile_stack_sample_table.h",
-        "src/trace_processor/db/bit_vector.cc",
-        "src/trace_processor/db/bit_vector.h",
-        "src/trace_processor/db/column.cc",
-        "src/trace_processor/db/column.h",
-        "src/trace_processor/db/row_map.cc",
-        "src/trace_processor/db/row_map.h",
-        "src/trace_processor/db/sparse_vector.h",
-        "src/trace_processor/db/table.cc",
-        "src/trace_processor/db/table.h",
-        "src/trace_processor/db/typed_column.h",
-        "src/trace_processor/event_tracker.cc",
-        "src/trace_processor/event_tracker.h",
-        "src/trace_processor/export_json.cc",
-        "src/trace_processor/export_json.h",
-        "src/trace_processor/filtered_row_index.cc",
-        "src/trace_processor/filtered_row_index.h",
-        "src/trace_processor/forwarding_trace_parser.cc",
-        "src/trace_processor/forwarding_trace_parser.h",
-        "src/trace_processor/ftrace_descriptors.cc",
-        "src/trace_processor/ftrace_descriptors.h",
-        "src/trace_processor/ftrace_utils.cc",
-        "src/trace_processor/ftrace_utils.h",
-        "src/trace_processor/fuchsia_provider_view.cc",
-        "src/trace_processor/fuchsia_provider_view.h",
-        "src/trace_processor/fuchsia_trace_parser.cc",
-        "src/trace_processor/fuchsia_trace_parser.h",
-        "src/trace_processor/fuchsia_trace_tokenizer.cc",
-        "src/trace_processor/fuchsia_trace_tokenizer.h",
-        "src/trace_processor/fuchsia_trace_utils.cc",
-        "src/trace_processor/fuchsia_trace_utils.h",
-        "src/trace_processor/graphics_frame_event_parser.cc",
-        "src/trace_processor/graphics_frame_event_parser.h",
-        "src/trace_processor/gzip_trace_parser.cc",
-        "src/trace_processor/gzip_trace_parser.h",
-        "src/trace_processor/heap_profile_allocation_table.cc",
-        "src/trace_processor/heap_profile_allocation_table.h",
-        "src/trace_processor/heap_profile_tracker.cc",
-        "src/trace_processor/heap_profile_tracker.h",
-        "src/trace_processor/instants_table.cc",
-        "src/trace_processor/instants_table.h",
-        "src/trace_processor/json_trace_parser.cc",
-        "src/trace_processor/json_trace_parser.h",
-        "src/trace_processor/json_trace_tokenizer.cc",
-        "src/trace_processor/json_trace_tokenizer.h",
-        "src/trace_processor/json_trace_utils.cc",
-        "src/trace_processor/json_trace_utils.h",
-        "src/trace_processor/metadata.h",
-        "src/trace_processor/metadata_table.cc",
-        "src/trace_processor/metadata_table.h",
-        "src/trace_processor/metrics/descriptors.cc",
-        "src/trace_processor/metrics/descriptors.h",
-        "src/trace_processor/metrics/metrics.cc",
-        "src/trace_processor/metrics/metrics.descriptor.h",
-        "src/trace_processor/metrics/metrics.h",
-        "src/trace_processor/metrics/sql_metrics.h",
-        "src/trace_processor/null_term_string_view.h",
-        "src/trace_processor/process_table.cc",
-        "src/trace_processor/process_table.h",
-        "src/trace_processor/process_tracker.cc",
-        "src/trace_processor/process_tracker.h",
-        "src/trace_processor/proto_incremental_state.h",
-        "src/trace_processor/proto_to_json.cc",
-        "src/trace_processor/proto_to_json.h",
-        "src/trace_processor/proto_trace_parser.cc",
-        "src/trace_processor/proto_trace_parser.h",
-        "src/trace_processor/proto_trace_tokenizer.cc",
-        "src/trace_processor/proto_trace_tokenizer.h",
-        "src/trace_processor/raw_table.cc",
-        "src/trace_processor/raw_table.h",
-        "src/trace_processor/row_iterators.cc",
-        "src/trace_processor/row_iterators.h",
-        "src/trace_processor/sched_slice_table.cc",
-        "src/trace_processor/sched_slice_table.h",
-        "src/trace_processor/slice_table.cc",
-        "src/trace_processor/slice_table.h",
-        "src/trace_processor/slice_tracker.cc",
-        "src/trace_processor/slice_tracker.h",
-        "src/trace_processor/span_join_operator_table.cc",
-        "src/trace_processor/span_join_operator_table.h",
-        "src/trace_processor/sql_stats_table.cc",
-        "src/trace_processor/sql_stats_table.h",
-        "src/trace_processor/sqlite/db_sqlite_table.cc",
-        "src/trace_processor/sqlite/db_sqlite_table.h",
-        "src/trace_processor/sqlite/query_constraints.cc",
-        "src/trace_processor/sqlite/query_constraints.h",
-        "src/trace_processor/sqlite/scoped_db.h",
-        "src/trace_processor/sqlite/sqlite3_str_split.cc",
-        "src/trace_processor/sqlite/sqlite3_str_split.h",
-        "src/trace_processor/sqlite/sqlite_table.cc",
-        "src/trace_processor/sqlite/sqlite_table.h",
-        "src/trace_processor/sqlite/sqlite_utils.h",
-        "src/trace_processor/stack_profile_callsite_table.cc",
-        "src/trace_processor/stack_profile_callsite_table.h",
-        "src/trace_processor/stack_profile_frame_table.cc",
-        "src/trace_processor/stack_profile_frame_table.h",
-        "src/trace_processor/stack_profile_mapping_table.cc",
-        "src/trace_processor/stack_profile_mapping_table.h",
-        "src/trace_processor/stack_profile_tracker.cc",
-        "src/trace_processor/stack_profile_tracker.h",
-        "src/trace_processor/stats.h",
-        "src/trace_processor/stats_table.cc",
-        "src/trace_processor/stats_table.h",
-        "src/trace_processor/storage_columns.cc",
-        "src/trace_processor/storage_columns.h",
-        "src/trace_processor/storage_schema.cc",
-        "src/trace_processor/storage_schema.h",
-        "src/trace_processor/storage_table.cc",
-        "src/trace_processor/storage_table.h",
-        "src/trace_processor/string_pool.cc",
-        "src/trace_processor/string_pool.h",
-        "src/trace_processor/syscall_tracker.cc",
-        "src/trace_processor/syscall_tracker.h",
-        "src/trace_processor/syscalls_aarch32.h",
-        "src/trace_processor/syscalls_aarch64.h",
-        "src/trace_processor/syscalls_armeabi.h",
-        "src/trace_processor/syscalls_x86_64.h",
-        "src/trace_processor/systrace_parser.cc",
-        "src/trace_processor/systrace_parser.h",
-        "src/trace_processor/systrace_trace_parser.cc",
-        "src/trace_processor/systrace_trace_parser.h",
-        "src/trace_processor/tables/macros.h",
-        "src/trace_processor/tables/macros_internal.h",
-        "src/trace_processor/tables/slice_tables.h",
-        "src/trace_processor/tables/track_tables.h",
-        "src/trace_processor/thread_table.cc",
-        "src/trace_processor/thread_table.h",
-        "src/trace_processor/trace_blob_view.h",
-        "src/trace_processor/trace_parser.h",
-        "src/trace_processor/trace_processor.cc",
-        "src/trace_processor/trace_processor_context.cc",
-        "src/trace_processor/trace_processor_context.h",
-        "src/trace_processor/trace_processor_impl.cc",
-        "src/trace_processor/trace_processor_impl.h",
-        "src/trace_processor/trace_processor_shell.cc",
-        "src/trace_processor/trace_sorter.cc",
-        "src/trace_processor/trace_sorter.h",
-        "src/trace_processor/trace_storage.cc",
-        "src/trace_processor/trace_storage.h",
-        "src/trace_processor/variadic.h",
-        "src/trace_processor/virtual_destructors.cc",
-        "src/trace_processor/virtual_track_tracker.cc",
-        "src/trace_processor/virtual_track_tracker.h",
-        "src/trace_processor/window_operator_table.cc",
-        "src/trace_processor/window_operator_table.h",
-    ],
-    deps = [
-        "//third_party/perfetto:gen_merged_sql_metrics",
-        "//third_party/perfetto/google:jsoncpp",
-        "//third_party/perfetto/google:linenoise",
-        "//third_party/perfetto/protos:common_zero_cc_proto",
-        "//third_party/perfetto/protos:config_android_zero_cc_proto",
-        "//third_party/perfetto/protos:config_ftrace_zero_cc_proto",
-        "//third_party/perfetto/protos:config_gpu_zero_cc_proto",
-        "//third_party/perfetto/protos:config_inode_file_zero_cc_proto",
-        "//third_party/perfetto/protos:config_power_zero_cc_proto",
-        "//third_party/perfetto/protos:config_process_stats_zero_cc_proto",
-        "//third_party/perfetto/protos:config_profiling_zero_cc_proto",
-        "//third_party/perfetto/protos:config_sys_stats_zero_cc_proto",
-        "//third_party/perfetto/protos:config_zero_cc_proto",
-        "//third_party/perfetto/protos:metrics_android_zero_cc_proto",
-        "//third_party/perfetto/protos:metrics_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_android_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_appended_data_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_chrome_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_filesystem_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_ftrace_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_gpu_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_interned_data_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_minimal_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_non_minimal_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_perfetto_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_power_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_processor_metrics_impl_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_profiling_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_ps_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_sys_stats_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_track_event_zero_cc_proto",
-        "//third_party/protobuf:libprotoc_legacy",
-        "//third_party/protobuf:protobuf_legacy",
-        "//third_party/sqlite",
-        "//third_party/sqlite:sqlite_ext_percentile",
-        "//third_party/zlib:zlibsystem",
+        "src/traced/probes/android_log/android_log_data_source.cc",
+        "src/traced/probes/android_log/android_log_data_source.h",
     ],
 )
 
-# GN target: //tools/trace_to_text:trace_to_text
-cc_binary(
-    name = "trace_to_text",
+# GN target: //src/traced/probes/filesystem:filesystem
+filegroup(
+    name = "src_traced_probes_filesystem_filesystem",
     srcs = [
-        "include/perfetto/base/build_config.h",
-        "include/perfetto/base/build_configs/bazel/perfetto_build_flags.h",
-        "include/perfetto/base/compiler.h",
-        "include/perfetto/base/copyable_ptr.h",
-        "include/perfetto/base/export.h",
-        "include/perfetto/base/logging.h",
-        "include/perfetto/base/task_runner.h",
-        "include/perfetto/base/time.h",
-        "include/perfetto/ext/base/circular_queue.h",
-        "include/perfetto/ext/base/container_annotations.h",
-        "include/perfetto/ext/base/event_fd.h",
-        "include/perfetto/ext/base/file_utils.h",
-        "include/perfetto/ext/base/hash.h",
-        "include/perfetto/ext/base/lookup_set.h",
-        "include/perfetto/ext/base/metatrace.h",
-        "include/perfetto/ext/base/metatrace_events.h",
-        "include/perfetto/ext/base/no_destructor.h",
-        "include/perfetto/ext/base/optional.h",
-        "include/perfetto/ext/base/paged_memory.h",
-        "include/perfetto/ext/base/pipe.h",
-        "include/perfetto/ext/base/proc_utils.h",
-        "include/perfetto/ext/base/scoped_file.h",
-        "include/perfetto/ext/base/small_set.h",
-        "include/perfetto/ext/base/string_splitter.h",
-        "include/perfetto/ext/base/string_utils.h",
-        "include/perfetto/ext/base/string_view.h",
-        "include/perfetto/ext/base/string_writer.h",
-        "include/perfetto/ext/base/temp_file.h",
-        "include/perfetto/ext/base/thread_annotations.h",
-        "include/perfetto/ext/base/thread_checker.h",
-        "include/perfetto/ext/base/thread_task_runner.h",
-        "include/perfetto/ext/base/thread_utils.h",
-        "include/perfetto/ext/base/unix_socket.h",
-        "include/perfetto/ext/base/unix_task_runner.h",
-        "include/perfetto/ext/base/utils.h",
-        "include/perfetto/ext/base/uuid.h",
-        "include/perfetto/ext/base/waitable_event.h",
-        "include/perfetto/ext/base/watchdog.h",
-        "include/perfetto/ext/base/watchdog_noop.h",
-        "include/perfetto/ext/base/watchdog_posix.h",
-        "include/perfetto/ext/base/weak_ptr.h",
-        "include/perfetto/ext/traced/sys_stats_counters.h",
-        "include/perfetto/protozero/contiguous_memory_range.h",
-        "include/perfetto/protozero/field.h",
-        "include/perfetto/protozero/message.h",
-        "include/perfetto/protozero/message_handle.h",
-        "include/perfetto/protozero/packed_repeated_fields.h",
-        "include/perfetto/protozero/proto_decoder.h",
-        "include/perfetto/protozero/proto_utils.h",
-        "include/perfetto/protozero/scattered_heap_buffer.h",
-        "include/perfetto/protozero/scattered_stream_null_delegate.h",
-        "include/perfetto/protozero/scattered_stream_writer.h",
-        "include/perfetto/trace_processor/basic_types.h",
-        "include/perfetto/trace_processor/status.h",
-        "include/perfetto/trace_processor/trace_processor.h",
-        "src/base/event_fd.cc",
-        "src/base/file_utils.cc",
-        "src/base/metatrace.cc",
-        "src/base/paged_memory.cc",
-        "src/base/pipe.cc",
-        "src/base/string_splitter.cc",
-        "src/base/string_utils.cc",
-        "src/base/string_view.cc",
-        "src/base/temp_file.cc",
-        "src/base/thread_checker.cc",
-        "src/base/thread_task_runner.cc",
-        "src/base/time.cc",
-        "src/base/unix_task_runner.cc",
-        "src/base/uuid.cc",
-        "src/base/virtual_destructors.cc",
-        "src/base/waitable_event.cc",
-        "src/base/watchdog_posix.cc",
-        "src/protozero/message.cc",
-        "src/protozero/message_handle.cc",
-        "src/protozero/proto_decoder.cc",
-        "src/protozero/scattered_heap_buffer.cc",
-        "src/protozero/scattered_stream_null_delegate.cc",
-        "src/protozero/scattered_stream_writer.cc",
-        "src/trace_processor/android_logs_table.cc",
-        "src/trace_processor/android_logs_table.h",
-        "src/trace_processor/args_table.cc",
-        "src/trace_processor/args_table.h",
-        "src/trace_processor/args_tracker.cc",
-        "src/trace_processor/args_tracker.h",
-        "src/trace_processor/chunked_trace_reader.h",
-        "src/trace_processor/clock_tracker.cc",
-        "src/trace_processor/clock_tracker.h",
-        "src/trace_processor/counter_definitions_table.cc",
-        "src/trace_processor/counter_definitions_table.h",
-        "src/trace_processor/counter_values_table.cc",
-        "src/trace_processor/counter_values_table.h",
-        "src/trace_processor/cpu_profile_stack_sample_table.cc",
-        "src/trace_processor/cpu_profile_stack_sample_table.h",
-        "src/trace_processor/db/bit_vector.cc",
-        "src/trace_processor/db/bit_vector.h",
-        "src/trace_processor/db/column.cc",
-        "src/trace_processor/db/column.h",
-        "src/trace_processor/db/row_map.cc",
-        "src/trace_processor/db/row_map.h",
-        "src/trace_processor/db/sparse_vector.h",
-        "src/trace_processor/db/table.cc",
-        "src/trace_processor/db/table.h",
-        "src/trace_processor/db/typed_column.h",
-        "src/trace_processor/event_tracker.cc",
-        "src/trace_processor/event_tracker.h",
-        "src/trace_processor/export_json.cc",
-        "src/trace_processor/export_json.h",
-        "src/trace_processor/filtered_row_index.cc",
-        "src/trace_processor/filtered_row_index.h",
-        "src/trace_processor/forwarding_trace_parser.cc",
-        "src/trace_processor/forwarding_trace_parser.h",
-        "src/trace_processor/ftrace_descriptors.cc",
-        "src/trace_processor/ftrace_descriptors.h",
-        "src/trace_processor/ftrace_utils.cc",
-        "src/trace_processor/ftrace_utils.h",
-        "src/trace_processor/fuchsia_provider_view.cc",
-        "src/trace_processor/fuchsia_provider_view.h",
-        "src/trace_processor/fuchsia_trace_parser.cc",
-        "src/trace_processor/fuchsia_trace_parser.h",
-        "src/trace_processor/fuchsia_trace_tokenizer.cc",
-        "src/trace_processor/fuchsia_trace_tokenizer.h",
-        "src/trace_processor/fuchsia_trace_utils.cc",
-        "src/trace_processor/fuchsia_trace_utils.h",
-        "src/trace_processor/graphics_frame_event_parser.cc",
-        "src/trace_processor/graphics_frame_event_parser.h",
-        "src/trace_processor/gzip_trace_parser.cc",
-        "src/trace_processor/gzip_trace_parser.h",
-        "src/trace_processor/heap_profile_allocation_table.cc",
-        "src/trace_processor/heap_profile_allocation_table.h",
-        "src/trace_processor/heap_profile_tracker.cc",
-        "src/trace_processor/heap_profile_tracker.h",
-        "src/trace_processor/instants_table.cc",
-        "src/trace_processor/instants_table.h",
-        "src/trace_processor/json_trace_parser.cc",
-        "src/trace_processor/json_trace_parser.h",
-        "src/trace_processor/json_trace_tokenizer.cc",
-        "src/trace_processor/json_trace_tokenizer.h",
-        "src/trace_processor/json_trace_utils.cc",
-        "src/trace_processor/json_trace_utils.h",
-        "src/trace_processor/metadata.h",
-        "src/trace_processor/metadata_table.cc",
-        "src/trace_processor/metadata_table.h",
-        "src/trace_processor/metrics/descriptors.cc",
-        "src/trace_processor/metrics/descriptors.h",
-        "src/trace_processor/metrics/metrics.cc",
-        "src/trace_processor/metrics/metrics.descriptor.h",
-        "src/trace_processor/metrics/metrics.h",
-        "src/trace_processor/metrics/sql_metrics.h",
-        "src/trace_processor/null_term_string_view.h",
-        "src/trace_processor/process_table.cc",
-        "src/trace_processor/process_table.h",
-        "src/trace_processor/process_tracker.cc",
-        "src/trace_processor/process_tracker.h",
-        "src/trace_processor/proto_incremental_state.h",
-        "src/trace_processor/proto_trace_parser.cc",
-        "src/trace_processor/proto_trace_parser.h",
-        "src/trace_processor/proto_trace_tokenizer.cc",
-        "src/trace_processor/proto_trace_tokenizer.h",
-        "src/trace_processor/raw_table.cc",
-        "src/trace_processor/raw_table.h",
-        "src/trace_processor/row_iterators.cc",
-        "src/trace_processor/row_iterators.h",
-        "src/trace_processor/sched_slice_table.cc",
-        "src/trace_processor/sched_slice_table.h",
-        "src/trace_processor/slice_table.cc",
-        "src/trace_processor/slice_table.h",
-        "src/trace_processor/slice_tracker.cc",
-        "src/trace_processor/slice_tracker.h",
-        "src/trace_processor/span_join_operator_table.cc",
-        "src/trace_processor/span_join_operator_table.h",
-        "src/trace_processor/sql_stats_table.cc",
-        "src/trace_processor/sql_stats_table.h",
-        "src/trace_processor/sqlite/db_sqlite_table.cc",
-        "src/trace_processor/sqlite/db_sqlite_table.h",
-        "src/trace_processor/sqlite/query_constraints.cc",
-        "src/trace_processor/sqlite/query_constraints.h",
-        "src/trace_processor/sqlite/scoped_db.h",
-        "src/trace_processor/sqlite/sqlite3_str_split.cc",
-        "src/trace_processor/sqlite/sqlite3_str_split.h",
-        "src/trace_processor/sqlite/sqlite_table.cc",
-        "src/trace_processor/sqlite/sqlite_table.h",
-        "src/trace_processor/sqlite/sqlite_utils.h",
-        "src/trace_processor/stack_profile_callsite_table.cc",
-        "src/trace_processor/stack_profile_callsite_table.h",
-        "src/trace_processor/stack_profile_frame_table.cc",
-        "src/trace_processor/stack_profile_frame_table.h",
-        "src/trace_processor/stack_profile_mapping_table.cc",
-        "src/trace_processor/stack_profile_mapping_table.h",
-        "src/trace_processor/stack_profile_tracker.cc",
-        "src/trace_processor/stack_profile_tracker.h",
-        "src/trace_processor/stats.h",
-        "src/trace_processor/stats_table.cc",
-        "src/trace_processor/stats_table.h",
-        "src/trace_processor/storage_columns.cc",
-        "src/trace_processor/storage_columns.h",
-        "src/trace_processor/storage_schema.cc",
-        "src/trace_processor/storage_schema.h",
-        "src/trace_processor/storage_table.cc",
-        "src/trace_processor/storage_table.h",
-        "src/trace_processor/string_pool.cc",
-        "src/trace_processor/string_pool.h",
-        "src/trace_processor/syscall_tracker.cc",
-        "src/trace_processor/syscall_tracker.h",
-        "src/trace_processor/syscalls_aarch32.h",
-        "src/trace_processor/syscalls_aarch64.h",
-        "src/trace_processor/syscalls_armeabi.h",
-        "src/trace_processor/syscalls_x86_64.h",
-        "src/trace_processor/systrace_parser.cc",
-        "src/trace_processor/systrace_parser.h",
-        "src/trace_processor/systrace_trace_parser.cc",
-        "src/trace_processor/systrace_trace_parser.h",
-        "src/trace_processor/tables/macros.h",
-        "src/trace_processor/tables/macros_internal.h",
-        "src/trace_processor/tables/slice_tables.h",
-        "src/trace_processor/tables/track_tables.h",
-        "src/trace_processor/thread_table.cc",
-        "src/trace_processor/thread_table.h",
-        "src/trace_processor/trace_blob_view.h",
-        "src/trace_processor/trace_parser.h",
-        "src/trace_processor/trace_processor.cc",
-        "src/trace_processor/trace_processor_context.cc",
-        "src/trace_processor/trace_processor_context.h",
-        "src/trace_processor/trace_processor_impl.cc",
-        "src/trace_processor/trace_processor_impl.h",
-        "src/trace_processor/trace_sorter.cc",
-        "src/trace_processor/trace_sorter.h",
-        "src/trace_processor/trace_storage.cc",
-        "src/trace_processor/trace_storage.h",
-        "src/trace_processor/variadic.h",
-        "src/trace_processor/virtual_destructors.cc",
-        "src/trace_processor/virtual_track_tracker.cc",
-        "src/trace_processor/virtual_track_tracker.h",
-        "src/trace_processor/window_operator_table.cc",
-        "src/trace_processor/window_operator_table.h",
-        "tools/trace_to_text/local_symbolizer.cc",
-        "tools/trace_to_text/local_symbolizer.h",
+        "src/traced/probes/filesystem/file_scanner.cc",
+        "src/traced/probes/filesystem/file_scanner.h",
+        "src/traced/probes/filesystem/fs_mount.cc",
+        "src/traced/probes/filesystem/fs_mount.h",
+        "src/traced/probes/filesystem/inode_file_data_source.cc",
+        "src/traced/probes/filesystem/inode_file_data_source.h",
+        "src/traced/probes/filesystem/lru_inode_cache.cc",
+        "src/traced/probes/filesystem/lru_inode_cache.h",
+        "src/traced/probes/filesystem/prefix_finder.cc",
+        "src/traced/probes/filesystem/prefix_finder.h",
+        "src/traced/probes/filesystem/range_tree.cc",
+        "src/traced/probes/filesystem/range_tree.h",
+    ],
+)
+
+# GN target: //src/traced/probes/ftrace:format_parser
+filegroup(
+    name = "src_traced_probes_ftrace_format_parser",
+    srcs = [
+        "src/traced/probes/ftrace/format_parser.cc",
+        "src/traced/probes/ftrace/format_parser.h",
+    ],
+)
+
+# GN target: //src/traced/probes/ftrace:ftrace
+filegroup(
+    name = "src_traced_probes_ftrace_ftrace",
+    srcs = [
+        "src/traced/probes/ftrace/atrace_hal_wrapper.cc",
+        "src/traced/probes/ftrace/atrace_hal_wrapper.h",
+        "src/traced/probes/ftrace/atrace_wrapper.cc",
+        "src/traced/probes/ftrace/atrace_wrapper.h",
+        "src/traced/probes/ftrace/compact_sched.cc",
+        "src/traced/probes/ftrace/compact_sched.h",
+        "src/traced/probes/ftrace/cpu_reader.cc",
+        "src/traced/probes/ftrace/cpu_reader.h",
+        "src/traced/probes/ftrace/cpu_stats_parser.cc",
+        "src/traced/probes/ftrace/cpu_stats_parser.h",
+        "src/traced/probes/ftrace/event_info.cc",
+        "src/traced/probes/ftrace/event_info.h",
+        "src/traced/probes/ftrace/event_info_constants.cc",
+        "src/traced/probes/ftrace/event_info_constants.h",
+        "src/traced/probes/ftrace/ftrace_config.cc",
+        "src/traced/probes/ftrace/ftrace_config.h",
+        "src/traced/probes/ftrace/ftrace_config_muxer.cc",
+        "src/traced/probes/ftrace/ftrace_config_muxer.h",
+        "src/traced/probes/ftrace/ftrace_config_utils.cc",
+        "src/traced/probes/ftrace/ftrace_config_utils.h",
+        "src/traced/probes/ftrace/ftrace_controller.cc",
+        "src/traced/probes/ftrace/ftrace_controller.h",
+        "src/traced/probes/ftrace/ftrace_data_source.cc",
+        "src/traced/probes/ftrace/ftrace_data_source.h",
+        "src/traced/probes/ftrace/ftrace_metadata.cc",
+        "src/traced/probes/ftrace/ftrace_metadata.h",
+        "src/traced/probes/ftrace/ftrace_procfs.cc",
+        "src/traced/probes/ftrace/ftrace_procfs.h",
+        "src/traced/probes/ftrace/ftrace_stats.cc",
+        "src/traced/probes/ftrace/ftrace_stats.h",
+        "src/traced/probes/ftrace/proto_translation_table.cc",
+        "src/traced/probes/ftrace/proto_translation_table.h",
+    ],
+)
+
+# GN target: //src/traced/probes/metatrace:metatrace
+filegroup(
+    name = "src_traced_probes_metatrace_metatrace",
+    srcs = [
+        "src/traced/probes/metatrace/metatrace_data_source.cc",
+        "src/traced/probes/metatrace/metatrace_data_source.h",
+    ],
+)
+
+# GN target: //src/traced/probes/packages_list:packages_list
+filegroup(
+    name = "src_traced_probes_packages_list_packages_list",
+    srcs = [
+        "src/traced/probes/packages_list/packages_list_data_source.cc",
+        "src/traced/probes/packages_list/packages_list_data_source.h",
+    ],
+)
+
+# GN target: //src/traced/probes/power:power
+filegroup(
+    name = "src_traced_probes_power_power",
+    srcs = [
+        "src/traced/probes/power/android_power_data_source.cc",
+        "src/traced/probes/power/android_power_data_source.h",
+    ],
+)
+
+# GN target: //src/traced/probes/ps:ps
+filegroup(
+    name = "src_traced_probes_ps_ps",
+    srcs = [
+        "src/traced/probes/ps/process_stats_data_source.cc",
+        "src/traced/probes/ps/process_stats_data_source.h",
+    ],
+)
+
+# GN target: //src/traced/probes/sys_stats:sys_stats
+filegroup(
+    name = "src_traced_probes_sys_stats_sys_stats",
+    srcs = [
+        "src/traced/probes/sys_stats/sys_stats_data_source.cc",
+        "src/traced/probes/sys_stats/sys_stats_data_source.h",
+    ],
+)
+
+# GN target: //src/traced/probes:data_source
+filegroup(
+    name = "src_traced_probes_data_source",
+    srcs = [
+        "src/traced/probes/probes_data_source.cc",
+        "src/traced/probes/probes_data_source.h",
+    ],
+)
+
+# GN target: //src/traced/probes:probes
+filegroup(
+    name = "src_traced_probes_probes",
+    srcs = [
+        "src/traced/probes/probes.cc",
+    ],
+)
+
+# GN target: //src/traced/probes:probes_src
+filegroup(
+    name = "src_traced_probes_probes_src",
+    srcs = [
+        "src/traced/probes/probes_producer.cc",
+        "src/traced/probes/probes_producer.h",
+    ],
+)
+
+# GN target: //src/traced/service:service
+filegroup(
+    name = "src_traced_service_service",
+    srcs = [
+        "src/traced/service/builtin_producer.cc",
+        "src/traced/service/builtin_producer.h",
+        "src/traced/service/service.cc",
+    ],
+)
+
+# GN target: //src/tracing:common
+filegroup(
+    name = "src_tracing_common",
+    srcs = [
+        "src/tracing/trace_writer_base.cc",
+    ],
+)
+
+# GN target: //src/tracing:consumer_api_deprecated
+filegroup(
+    name = "src_tracing_consumer_api_deprecated",
+    srcs = [
+        "src/tracing/api_impl/consumer_api.cc",
+    ],
+)
+
+# GN target: //src/tracing:ipc
+filegroup(
+    name = "src_tracing_ipc",
+    srcs = [
+        "src/tracing/ipc/consumer/consumer_ipc_client_impl.cc",
+        "src/tracing/ipc/consumer/consumer_ipc_client_impl.h",
+        "src/tracing/ipc/default_socket.cc",
+        "src/tracing/ipc/posix_shared_memory.cc",
+        "src/tracing/ipc/posix_shared_memory.h",
+        "src/tracing/ipc/producer/producer_ipc_client_impl.cc",
+        "src/tracing/ipc/producer/producer_ipc_client_impl.h",
+        "src/tracing/ipc/service/consumer_ipc_service.cc",
+        "src/tracing/ipc/service/consumer_ipc_service.h",
+        "src/tracing/ipc/service/producer_ipc_service.cc",
+        "src/tracing/ipc/service/producer_ipc_service.h",
+        "src/tracing/ipc/service/service_ipc_host_impl.cc",
+        "src/tracing/ipc/service/service_ipc_host_impl.h",
+    ],
+)
+
+# GN target: //src/tracing:tracing
+filegroup(
+    name = "src_tracing_tracing",
+    srcs = [
+        "src/tracing/core/chrome_config.cc",
+        "src/tracing/core/commit_data_request.cc",
+        "src/tracing/core/data_source_config.cc",
+        "src/tracing/core/data_source_descriptor.cc",
+        "src/tracing/core/id_allocator.cc",
+        "src/tracing/core/id_allocator.h",
+        "src/tracing/core/metatrace_writer.cc",
+        "src/tracing/core/metatrace_writer.h",
+        "src/tracing/core/null_trace_writer.cc",
+        "src/tracing/core/null_trace_writer.h",
+        "src/tracing/core/observable_events.cc",
+        "src/tracing/core/packet_stream_validator.cc",
+        "src/tracing/core/packet_stream_validator.h",
+        "src/tracing/core/patch_list.h",
+        "src/tracing/core/shared_memory_abi.cc",
+        "src/tracing/core/shared_memory_arbiter_impl.cc",
+        "src/tracing/core/shared_memory_arbiter_impl.h",
+        "src/tracing/core/sliced_protobuf_input_stream.cc",
+        "src/tracing/core/startup_trace_writer.cc",
+        "src/tracing/core/startup_trace_writer_registry.cc",
+        "src/tracing/core/test_config.cc",
+        "src/tracing/core/trace_buffer.cc",
+        "src/tracing/core/trace_buffer.h",
+        "src/tracing/core/trace_config.cc",
+        "src/tracing/core/trace_packet.cc",
+        "src/tracing/core/trace_stats.cc",
+        "src/tracing/core/trace_writer_impl.cc",
+        "src/tracing/core/trace_writer_impl.h",
+        "src/tracing/core/tracing_service_impl.cc",
+        "src/tracing/core/tracing_service_impl.h",
+        "src/tracing/core/tracing_service_state.cc",
+        "src/tracing/core/virtual_destructors.cc",
+    ],
+)
+
+# GN target: //tools/trace_to_text:common
+filegroup(
+    name = "tools_trace_to_text_common",
+    srcs = [
         "tools/trace_to_text/main.cc",
-        "tools/trace_to_text/pprof_builder.cc",
-        "tools/trace_to_text/pprof_builder.h",
-        "tools/trace_to_text/profile_visitor.cc",
-        "tools/trace_to_text/profile_visitor.h",
-        "tools/trace_to_text/proto_full_utils.cc",
-        "tools/trace_to_text/proto_full_utils.h",
         "tools/trace_to_text/symbolize_profile.cc",
         "tools/trace_to_text/symbolize_profile.h",
-        "tools/trace_to_text/symbolizer.cc",
-        "tools/trace_to_text/symbolizer.h",
-        "tools/trace_to_text/trace_symbol_table.cc",
-        "tools/trace_to_text/trace_symbol_table.h",
         "tools/trace_to_text/trace_to_profile.cc",
         "tools/trace_to_text/trace_to_profile.h",
         "tools/trace_to_text/trace_to_systrace.cc",
         "tools/trace_to_text/trace_to_systrace.h",
-        "tools/trace_to_text/trace_to_text.cc",
         "tools/trace_to_text/trace_to_text.h",
-        "tools/trace_to_text/utils.cc",
-        "tools/trace_to_text/utils.h",
-    ],
-    deps = [
-        "//third_party/perfetto:gen_merged_sql_metrics",
-        "//third_party/perfetto/google:jsoncpp",
-        "//third_party/perfetto/protos:common_cc_proto",
-        "//third_party/perfetto/protos:common_zero_cc_proto",
-        "//third_party/perfetto/protos:config_android_cc_proto",
-        "//third_party/perfetto/protos:config_android_zero_cc_proto",
-        "//third_party/perfetto/protos:config_cc_proto",
-        "//third_party/perfetto/protos:config_ftrace_cc_proto",
-        "//third_party/perfetto/protos:config_ftrace_zero_cc_proto",
-        "//third_party/perfetto/protos:config_gpu_cc_proto",
-        "//third_party/perfetto/protos:config_gpu_zero_cc_proto",
-        "//third_party/perfetto/protos:config_inode_file_cc_proto",
-        "//third_party/perfetto/protos:config_inode_file_zero_cc_proto",
-        "//third_party/perfetto/protos:config_power_cc_proto",
-        "//third_party/perfetto/protos:config_power_zero_cc_proto",
-        "//third_party/perfetto/protos:config_process_stats_cc_proto",
-        "//third_party/perfetto/protos:config_process_stats_zero_cc_proto",
-        "//third_party/perfetto/protos:config_profiling_cc_proto",
-        "//third_party/perfetto/protos:config_profiling_zero_cc_proto",
-        "//third_party/perfetto/protos:config_sys_stats_cc_proto",
-        "//third_party/perfetto/protos:config_sys_stats_zero_cc_proto",
-        "//third_party/perfetto/protos:config_zero_cc_proto",
-        "//third_party/perfetto/protos:metrics_android_zero_cc_proto",
-        "//third_party/perfetto/protos:metrics_zero_cc_proto",
-        "//third_party/perfetto/protos:protos_third_party_pprof_cc_proto",
-        "//third_party/perfetto/protos:trace_android_cc_proto",
-        "//third_party/perfetto/protos:trace_android_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_appended_data_cc_proto",
-        "//third_party/perfetto/protos:trace_appended_data_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_chrome_cc_proto",
-        "//third_party/perfetto/protos:trace_chrome_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_filesystem_cc_proto",
-        "//third_party/perfetto/protos:trace_filesystem_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_ftrace_cc_proto",
-        "//third_party/perfetto/protos:trace_ftrace_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_gpu_cc_proto",
-        "//third_party/perfetto/protos:trace_gpu_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_interned_data_cc_proto",
-        "//third_party/perfetto/protos:trace_interned_data_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_minimal_cc_proto",
-        "//third_party/perfetto/protos:trace_minimal_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_non_minimal_cc_proto",
-        "//third_party/perfetto/protos:trace_non_minimal_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_perfetto_cc_proto",
-        "//third_party/perfetto/protos:trace_perfetto_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_power_cc_proto",
-        "//third_party/perfetto/protos:trace_power_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_processor_metrics_impl_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_profiling_cc_proto",
-        "//third_party/perfetto/protos:trace_profiling_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_ps_cc_proto",
-        "//third_party/perfetto/protos:trace_ps_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_sys_stats_cc_proto",
-        "//third_party/perfetto/protos:trace_sys_stats_zero_cc_proto",
-        "//third_party/perfetto/protos:trace_track_event_cc_proto",
-        "//third_party/perfetto/protos:trace_track_event_zero_cc_proto",
-        "//third_party/protobuf:libprotoc_legacy",
-        "//third_party/protobuf:protobuf_legacy",
-        "//third_party/sqlite",
-        "//third_party/sqlite:sqlite_ext_percentile",
-        "//third_party/zlib:zlibsystem",
     ],
 )
 
-gensignature(
+# GN target: //tools/trace_to_text:full
+filegroup(
+    name = "tools_trace_to_text_full",
+    srcs = [
+        "tools/trace_to_text/proto_full_utils.cc",
+        "tools/trace_to_text/proto_full_utils.h",
+        "tools/trace_to_text/trace_to_text.cc",
+    ],
+)
+
+# GN target: //tools/trace_to_text:local_symbolizer
+filegroup(
+    name = "tools_trace_to_text_local_symbolizer",
+    srcs = [
+        "tools/trace_to_text/local_symbolizer.cc",
+        "tools/trace_to_text/local_symbolizer.h",
+    ],
+)
+
+# GN target: //tools/trace_to_text:pprofbuilder
+filegroup(
+    name = "tools_trace_to_text_pprofbuilder",
+    srcs = [
+        "tools/trace_to_text/pprof_builder.cc",
+        "tools/trace_to_text/pprof_builder.h",
+    ],
+)
+
+# GN target: //tools/trace_to_text:symbolizer
+filegroup(
+    name = "tools_trace_to_text_symbolizer",
+    srcs = [
+        "tools/trace_to_text/symbolizer.cc",
+        "tools/trace_to_text/symbolizer.h",
+        "tools/trace_to_text/trace_symbol_table.cc",
+        "tools/trace_to_text/trace_symbol_table.h",
+    ],
+)
+
+# GN target: //tools/trace_to_text:utils
+filegroup(
+    name = "tools_trace_to_text_utils",
+    srcs = [
+        "tools/trace_to_text/profile_visitor.cc",
+        "tools/trace_to_text/profile_visitor.h",
+        "tools/trace_to_text/utils.cc",
+        "tools/trace_to_text/utils.h",
+    ],
+)
+
+# ##############################################################################
+# Proto libraries
+# ##############################################################################
+
+# GN target: //protos/perfetto/trace_processor:metrics_impl_zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_trace_processor_metrics_impl_zero",
+    deps = [
+        ":protos_perfetto_trace_processor_metrics_impl_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/filesystem:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_trace_filesystem_lite",
+    deps = [
+        ":protos_perfetto_trace_filesystem_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/power:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_trace_power_lite",
+    deps = [
+        ":protos_perfetto_trace_power_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/track_event:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_trace_track_event_lite",
+    deps = [
+        ":protos_perfetto_trace_track_event_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/config/process_stats:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_config_process_stats_zero",
+    deps = [
+        ":protos_perfetto_config_process_stats_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/perfetto:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_trace_perfetto_zero",
+    deps = [
+        ":protos_perfetto_trace_perfetto_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/config/power:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_config_power_zero",
+    deps = [
+        ":protos_perfetto_config_power_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/config/sys_stats:lite
+perfetto_proto_library(
+    name = "protos_perfetto_config_sys_stats_protos",
+    srcs = [
+        "protos/perfetto/config/sys_stats/sys_stats_config.proto",
+    ],
+    deps = [
+        ":protos_perfetto_common_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/metrics:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_metrics_lite",
+    deps = [
+        ":protos_perfetto_metrics_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/config/sys_stats:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_config_sys_stats_lite",
+    deps = [
+        ":protos_perfetto_config_sys_stats_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/metrics:lite
+perfetto_proto_library(
+    name = "protos_perfetto_metrics_protos",
+    srcs = [
+        "protos/perfetto/metrics/metrics.proto",
+    ],
+    deps = [
+        ":protos_perfetto_metrics_android_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/config/android:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_config_android_lite",
+    deps = [
+        ":protos_perfetto_config_android_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/interned_data:zero
+perfetto_proto_library(
+    name = "protos_perfetto_trace_interned_data_protos",
+    srcs = [
+        "protos/perfetto/trace/interned_data/interned_data.proto",
+    ],
+    deps = [
+        ":protos_perfetto_trace_profiling_protos",
+        ":protos_perfetto_trace_track_event_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace:minimal_lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_trace_minimal_lite",
+    deps = [
+        ":protos_perfetto_trace_minimal_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace:non_minimal_zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_trace_non_minimal_zero",
+    deps = [
+        ":protos_perfetto_trace_non_minimal_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/metrics/android:zero
+perfetto_proto_library(
+    name = "protos_perfetto_metrics_android_protos",
+    srcs = [
+        "protos/perfetto/metrics/android/batt_metric.proto",
+        "protos/perfetto/metrics/android/cpu_metric.proto",
+        "protos/perfetto/metrics/android/heap_profile_callsite_stats.proto",
+        "protos/perfetto/metrics/android/ion_metric.proto",
+        "protos/perfetto/metrics/android/lmk_metric.proto",
+        "protos/perfetto/metrics/android/mem_metric.proto",
+        "protos/perfetto/metrics/android/mem_unagg_metric.proto",
+        "protos/perfetto/metrics/android/package_list.proto",
+        "protos/perfetto/metrics/android/powrails_metric.proto",
+        "protos/perfetto/metrics/android/process_growth.proto",
+        "protos/perfetto/metrics/android/startup_metric.proto",
+    ],
+)
+
+# GN target: //protos/perfetto/config/inode_file:zero
+perfetto_proto_library(
+    name = "protos_perfetto_config_inode_file_protos",
+    srcs = [
+        "protos/perfetto/config/inode_file/inode_file_config.proto",
+    ],
+)
+
+# GN target: //protos/perfetto/config/gpu:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_config_gpu_zero",
+    deps = [
+        ":protos_perfetto_config_gpu_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/chrome:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_trace_chrome_zero",
+    deps = [
+        ":protos_perfetto_trace_chrome_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/common:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_common_zero",
+    deps = [
+        ":protos_perfetto_common_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/config/android:lite
+perfetto_proto_library(
+    name = "protos_perfetto_config_android_protos",
+    srcs = [
+        "protos/perfetto/config/android/android_log_config.proto",
+        "protos/perfetto/config/android/packages_list_config.proto",
+    ],
+    deps = [
+        ":protos_perfetto_common_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/config/power:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_config_power_lite",
+    deps = [
+        ":protos_perfetto_config_power_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/android:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_trace_android_zero",
+    deps = [
+        ":protos_perfetto_trace_android_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/config/profiling:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_config_profiling_zero",
+    deps = [
+        ":protos_perfetto_config_profiling_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/metrics/android:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_metrics_android_lite",
+    deps = [
+        ":protos_perfetto_metrics_android_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/appended_data:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_trace_appended_data_lite",
+    deps = [
+        ":protos_perfetto_trace_appended_data_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/power:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_trace_power_zero",
+    deps = [
+        ":protos_perfetto_trace_power_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/gpu:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_trace_gpu_zero",
+    deps = [
+        ":protos_perfetto_trace_gpu_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/sys_stats:lite
+perfetto_proto_library(
+    name = "protos_perfetto_trace_sys_stats_protos",
+    srcs = [
+        "protos/perfetto/trace/sys_stats/sys_stats.proto",
+    ],
+    deps = [
+        ":protos_perfetto_common_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/config/gpu:lite
+perfetto_proto_library(
+    name = "protos_perfetto_config_gpu_protos",
+    srcs = [
+        "protos/perfetto/config/gpu/gpu_counter_config.proto",
+    ],
+)
+
+# GN target: //protos/perfetto/common:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_common_lite",
+    deps = [
+        ":protos_perfetto_common_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/ftrace:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_trace_ftrace_lite",
+    deps = [
+        ":protos_perfetto_trace_ftrace_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/filesystem:zero
+perfetto_proto_library(
+    name = "protos_perfetto_trace_filesystem_protos",
+    srcs = [
+        "protos/perfetto/trace/filesystem/inode_file_map.proto",
+    ],
+)
+
+# GN target: //protos/third_party/pprof:lite
+perfetto_proto_library(
+    name = "protos_third_party_pprof_protos",
+    srcs = [
+        "protos/third_party/pprof/profile.proto",
+    ],
+)
+
+# GN target: //protos/perfetto/config/process_stats:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_config_process_stats_lite",
+    deps = [
+        ":protos_perfetto_config_process_stats_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/appended_data:zero
+perfetto_proto_library(
+    name = "protos_perfetto_trace_appended_data_protos",
+    srcs = [
+        "protos/perfetto/trace/appended_data/appended_data.proto",
+    ],
+    deps = [
+        ":protos_perfetto_trace_profiling_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/config:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_config_lite",
+    deps = [
+        ":protos_perfetto_config_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/ftrace:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_trace_ftrace_zero",
+    deps = [
+        ":protos_perfetto_trace_ftrace_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/profiling:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_trace_profiling_zero",
+    deps = [
+        ":protos_perfetto_trace_profiling_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/ipc:ipc
+perfetto_cc_ipc_library(
+    name = "protos_perfetto_ipc_ipc",
+    deps = [
+        ":protos_perfetto_ipc_ipc_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/config/android:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_config_android_zero",
+    deps = [
+        ":protos_perfetto_config_android_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/gpu:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_trace_gpu_lite",
+    deps = [
+        ":protos_perfetto_trace_gpu_protos",
+    ],
+)
+
+# GN target: //src/perfetto_cmd:protos
+perfetto_cc_proto_library(
+    name = "src_perfetto_cmd_protos",
+    deps = [
+        ":src_perfetto_cmd_protos_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/config/power:zero
+perfetto_proto_library(
+    name = "protos_perfetto_config_power_protos",
+    srcs = [
+        "protos/perfetto/config/power/android_power_config.proto",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/chrome:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_trace_chrome_lite",
+    deps = [
+        ":protos_perfetto_trace_chrome_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace:minimal_zero
+perfetto_proto_library(
+    name = "protos_perfetto_trace_minimal_protos",
+    srcs = [
+        "protos/perfetto/trace/clock_snapshot.proto",
+        "protos/perfetto/trace/system_info.proto",
+        "protos/perfetto/trace/trigger.proto",
+    ],
+    deps = [
+        ":protos_perfetto_common_protos",
+        ":protos_perfetto_config_android_protos",
+        ":protos_perfetto_config_ftrace_protos",
+        ":protos_perfetto_config_gpu_protos",
+        ":protos_perfetto_config_inode_file_protos",
+        ":protos_perfetto_config_power_protos",
+        ":protos_perfetto_config_process_stats_protos",
+        ":protos_perfetto_config_profiling_protos",
+        ":protos_perfetto_config_protos",
+        ":protos_perfetto_config_sys_stats_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/perfetto:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_trace_perfetto_lite",
+    deps = [
+        ":protos_perfetto_trace_perfetto_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace:non_minimal_lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_trace_non_minimal_lite",
+    deps = [
+        ":protos_perfetto_trace_non_minimal_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/gpu:zero
+perfetto_proto_library(
+    name = "protos_perfetto_trace_gpu_protos",
+    srcs = [
+        "protos/perfetto/trace/gpu/gpu_counter_event.proto",
+        "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
+    ],
+    deps = [
+        ":protos_perfetto_common_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/track_event:lite
+perfetto_proto_library(
+    name = "protos_perfetto_trace_track_event_protos",
+    srcs = [
+        "protos/perfetto/trace/track_event/debug_annotation.proto",
+        "protos/perfetto/trace/track_event/log_message.proto",
+        "protos/perfetto/trace/track_event/process_descriptor.proto",
+        "protos/perfetto/trace/track_event/source_location.proto",
+        "protos/perfetto/trace/track_event/task_execution.proto",
+        "protos/perfetto/trace/track_event/thread_descriptor.proto",
+        "protos/perfetto/trace/track_event/track_descriptor.proto",
+        "protos/perfetto/trace/track_event/track_event.proto",
+    ],
+)
+
+# GN target: //protos/perfetto/ipc:ipc
+perfetto_proto_library(
+    name = "protos_perfetto_ipc_ipc_protos",
+    srcs = [
+        "protos/perfetto/ipc/consumer_port.proto",
+        "protos/perfetto/ipc/producer_port.proto",
+    ],
+    deps = [
+        ":protos_perfetto_common_protos",
+        ":protos_perfetto_config_android_protos",
+        ":protos_perfetto_config_ftrace_protos",
+        ":protos_perfetto_config_gpu_protos",
+        ":protos_perfetto_config_inode_file_protos",
+        ":protos_perfetto_config_power_protos",
+        ":protos_perfetto_config_process_stats_protos",
+        ":protos_perfetto_config_profiling_protos",
+        ":protos_perfetto_config_protos",
+        ":protos_perfetto_config_sys_stats_protos",
+        ":protos_perfetto_ipc_wire_protocol_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/metrics:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_metrics_zero",
+    deps = [
+        ":protos_perfetto_metrics_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/sys_stats:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_trace_sys_stats_zero",
+    deps = [
+        ":protos_perfetto_trace_sys_stats_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/config/gpu:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_config_gpu_lite",
+    deps = [
+        ":protos_perfetto_config_gpu_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/chrome:lite
+perfetto_proto_library(
+    name = "protos_perfetto_trace_chrome_protos",
+    srcs = [
+        "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
+        "protos/perfetto/trace/chrome/chrome_metadata.proto",
+        "protos/perfetto/trace/chrome/chrome_trace_event.proto",
+    ],
+)
+
+# GN target: //protos/perfetto/config/ftrace:lite
+perfetto_proto_library(
+    name = "protos_perfetto_config_ftrace_protos",
+    srcs = [
+        "protos/perfetto/config/ftrace/ftrace_config.proto",
+    ],
+)
+
+# GN target: //protos/perfetto/config/ftrace:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_config_ftrace_lite",
+    deps = [
+        ":protos_perfetto_config_ftrace_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/sys_stats:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_trace_sys_stats_lite",
+    deps = [
+        ":protos_perfetto_trace_sys_stats_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/ipc:wire_protocol
+perfetto_proto_library(
+    name = "protos_perfetto_ipc_wire_protocol_protos",
+    srcs = [
+        "protos/perfetto/ipc/wire_protocol.proto",
+    ],
+)
+
+# GN target: //protos/perfetto/config/sys_stats:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_config_sys_stats_zero",
+    deps = [
+        ":protos_perfetto_config_sys_stats_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/config/inode_file:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_config_inode_file_lite",
+    deps = [
+        ":protos_perfetto_config_inode_file_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/ps:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_trace_ps_zero",
+    deps = [
+        ":protos_perfetto_trace_ps_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace_processor:metrics_impl_zero
+perfetto_proto_library(
+    name = "protos_perfetto_trace_processor_metrics_impl_protos",
+    srcs = [
+        "protos/perfetto/trace_processor/metrics_impl.proto",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/interned_data:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_trace_interned_data_zero",
+    deps = [
+        ":protos_perfetto_trace_interned_data_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/interned_data:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_trace_interned_data_lite",
+    deps = [
+        ":protos_perfetto_trace_interned_data_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/ftrace:lite
+perfetto_proto_library(
+    name = "protos_perfetto_trace_ftrace_protos",
+    srcs = [
+        "protos/perfetto/trace/ftrace/binder.proto",
+        "protos/perfetto/trace/ftrace/block.proto",
+        "protos/perfetto/trace/ftrace/cgroup.proto",
+        "protos/perfetto/trace/ftrace/clk.proto",
+        "protos/perfetto/trace/ftrace/compaction.proto",
+        "protos/perfetto/trace/ftrace/ext4.proto",
+        "protos/perfetto/trace/ftrace/f2fs.proto",
+        "protos/perfetto/trace/ftrace/fence.proto",
+        "protos/perfetto/trace/ftrace/filemap.proto",
+        "protos/perfetto/trace/ftrace/ftrace.proto",
+        "protos/perfetto/trace/ftrace/ftrace_event.proto",
+        "protos/perfetto/trace/ftrace/ftrace_event_bundle.proto",
+        "protos/perfetto/trace/ftrace/ftrace_stats.proto",
+        "protos/perfetto/trace/ftrace/generic.proto",
+        "protos/perfetto/trace/ftrace/i2c.proto",
+        "protos/perfetto/trace/ftrace/ipi.proto",
+        "protos/perfetto/trace/ftrace/irq.proto",
+        "protos/perfetto/trace/ftrace/kmem.proto",
+        "protos/perfetto/trace/ftrace/lowmemorykiller.proto",
+        "protos/perfetto/trace/ftrace/mdss.proto",
+        "protos/perfetto/trace/ftrace/mm_event.proto",
+        "protos/perfetto/trace/ftrace/oom.proto",
+        "protos/perfetto/trace/ftrace/power.proto",
+        "protos/perfetto/trace/ftrace/raw_syscalls.proto",
+        "protos/perfetto/trace/ftrace/regulator.proto",
+        "protos/perfetto/trace/ftrace/sched.proto",
+        "protos/perfetto/trace/ftrace/signal.proto",
+        "protos/perfetto/trace/ftrace/sync.proto",
+        "protos/perfetto/trace/ftrace/systrace.proto",
+        "protos/perfetto/trace/ftrace/task.proto",
+        "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
+        "protos/perfetto/trace/ftrace/vmscan.proto",
+        "protos/perfetto/trace/ftrace/workqueue.proto",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/perfetto:lite
+perfetto_proto_library(
+    name = "protos_perfetto_trace_perfetto_protos",
+    srcs = [
+        "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
+    ],
+)
+
+# GN target: //protos/perfetto/common:zero
+perfetto_proto_library(
+    name = "protos_perfetto_common_protos",
+    srcs = [
+        "protos/perfetto/common/android_log_constants.proto",
+        "protos/perfetto/common/commit_data_request.proto",
+        "protos/perfetto/common/data_source_descriptor.proto",
+        "protos/perfetto/common/descriptor.proto",
+        "protos/perfetto/common/gpu_counter_descriptor.proto",
+        "protos/perfetto/common/observable_events.proto",
+        "protos/perfetto/common/sys_stats_counters.proto",
+        "protos/perfetto/common/trace_stats.proto",
+        "protos/perfetto/common/tracing_service_state.proto",
+        "protos/perfetto/common/track_event_descriptor.proto",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/profiling:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_trace_profiling_lite",
+    deps = [
+        ":protos_perfetto_trace_profiling_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace:trusted_lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_trace_trusted_lite",
+    deps = [
+        ":protos_perfetto_trace_trusted_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/ps:zero
+perfetto_proto_library(
+    name = "protos_perfetto_trace_ps_protos",
+    srcs = [
+        "protos/perfetto/trace/ps/process_stats.proto",
+        "protos/perfetto/trace/ps/process_tree.proto",
+    ],
+)
+
+# GN target: //protos/perfetto/trace:minimal_zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_trace_minimal_zero",
+    deps = [
+        ":protos_perfetto_trace_minimal_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/filesystem:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_trace_filesystem_zero",
+    deps = [
+        ":protos_perfetto_trace_filesystem_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/config/profiling:zero
+perfetto_proto_library(
+    name = "protos_perfetto_config_profiling_protos",
+    srcs = [
+        "protos/perfetto/config/profiling/heapprofd_config.proto",
+        "protos/perfetto/config/profiling/java_hprof_config.proto",
+    ],
+)
+
+# GN target: //protos/perfetto/metrics/android:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_metrics_android_zero",
+    deps = [
+        ":protos_perfetto_metrics_android_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/power:lite
+perfetto_proto_library(
+    name = "protos_perfetto_trace_power_protos",
+    srcs = [
+        "protos/perfetto/trace/power/battery_counters.proto",
+        "protos/perfetto/trace/power/power_rails.proto",
+    ],
+)
+
+# GN target: //protos/perfetto/ipc:wire_protocol
+perfetto_cc_proto_library(
+    name = "protos_perfetto_ipc_wire_protocol",
+    deps = [
+        ":protos_perfetto_ipc_wire_protocol_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/android:lite
+perfetto_proto_library(
+    name = "protos_perfetto_trace_android_protos",
+    srcs = [
+        "protos/perfetto/trace/android/android_log.proto",
+        "protos/perfetto/trace/android/graphics_frame_event.proto",
+        "protos/perfetto/trace/android/packages_list.proto",
+    ],
+    deps = [
+        ":protos_perfetto_common_protos",
+    ],
+)
+
+# GN target: //src/perfetto_cmd:protos
+perfetto_proto_library(
+    name = "src_perfetto_cmd_protos_protos",
+    srcs = [
+        "src/perfetto_cmd/perfetto_cmd_state.proto",
+    ],
+)
+
+# GN target: //protos/perfetto/config:zero
+perfetto_proto_library(
+    name = "protos_perfetto_config_protos",
+    srcs = [
+        "protos/perfetto/config/chrome/chrome_config.proto",
+        "protos/perfetto/config/data_source_config.proto",
+        "protos/perfetto/config/test_config.proto",
+        "protos/perfetto/config/trace_config.proto",
+    ],
+    deps = [
+        ":protos_perfetto_common_protos",
+        ":protos_perfetto_config_android_protos",
+        ":protos_perfetto_config_ftrace_protos",
+        ":protos_perfetto_config_gpu_protos",
+        ":protos_perfetto_config_inode_file_protos",
+        ":protos_perfetto_config_power_protos",
+        ":protos_perfetto_config_process_stats_protos",
+        ":protos_perfetto_config_profiling_protos",
+        ":protos_perfetto_config_sys_stats_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/profiling:lite
+perfetto_proto_library(
+    name = "protos_perfetto_trace_profiling_protos",
+    srcs = [
+        "protos/perfetto/trace/profiling/heap_graph.proto",
+        "protos/perfetto/trace/profiling/profile_common.proto",
+        "protos/perfetto/trace/profiling/profile_packet.proto",
+    ],
+)
+
+# GN target: //protos/perfetto/trace:trusted_lite
+perfetto_proto_library(
+    name = "protos_perfetto_trace_trusted_protos",
+    srcs = [
+        "protos/perfetto/trace/trusted_packet.proto",
+    ],
+    deps = [
+        ":protos_perfetto_common_protos",
+        ":protos_perfetto_config_android_protos",
+        ":protos_perfetto_config_ftrace_protos",
+        ":protos_perfetto_config_gpu_protos",
+        ":protos_perfetto_config_inode_file_protos",
+        ":protos_perfetto_config_power_protos",
+        ":protos_perfetto_config_process_stats_protos",
+        ":protos_perfetto_config_profiling_protos",
+        ":protos_perfetto_config_protos",
+        ":protos_perfetto_config_sys_stats_protos",
+        ":protos_perfetto_trace_minimal_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/appended_data:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_trace_appended_data_zero",
+    deps = [
+        ":protos_perfetto_trace_appended_data_protos",
+    ],
+)
+
+# GN target: //protos/third_party/pprof:lite
+perfetto_cc_proto_library(
+    name = "protos_third_party_pprof_lite",
+    deps = [
+        ":protos_third_party_pprof_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/config/ftrace:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_config_ftrace_zero",
+    deps = [
+        ":protos_perfetto_config_ftrace_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/android:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_trace_android_lite",
+    deps = [
+        ":protos_perfetto_trace_android_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/config/profiling:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_config_profiling_lite",
+    deps = [
+        ":protos_perfetto_config_profiling_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/config:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_config_zero",
+    deps = [
+        ":protos_perfetto_config_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/ps:lite
+perfetto_cc_proto_library(
+    name = "protos_perfetto_trace_ps_lite",
+    deps = [
+        ":protos_perfetto_trace_ps_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace/track_event:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_trace_track_event_zero",
+    deps = [
+        ":protos_perfetto_trace_track_event_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/config/process_stats:zero
+perfetto_proto_library(
+    name = "protos_perfetto_config_process_stats_protos",
+    srcs = [
+        "protos/perfetto/config/process_stats/process_stats_config.proto",
+    ],
+)
+
+# GN target: //protos/perfetto/config/inode_file:zero
+perfetto_cc_protozero_library(
+    name = "protos_perfetto_config_inode_file_zero",
+    deps = [
+        ":protos_perfetto_config_inode_file_protos",
+    ],
+)
+
+# GN target: //protos/perfetto/trace:non_minimal_lite
+perfetto_proto_library(
+    name = "protos_perfetto_trace_non_minimal_protos",
+    srcs = [
+        "protos/perfetto/trace/test_event.proto",
+        "protos/perfetto/trace/trace.proto",
+        "protos/perfetto/trace/trace_packet.proto",
+        "protos/perfetto/trace/trace_packet_defaults.proto",
+    ],
+    deps = [
+        ":protos_perfetto_common_protos",
+        ":protos_perfetto_config_android_protos",
+        ":protos_perfetto_config_ftrace_protos",
+        ":protos_perfetto_config_gpu_protos",
+        ":protos_perfetto_config_inode_file_protos",
+        ":protos_perfetto_config_power_protos",
+        ":protos_perfetto_config_process_stats_protos",
+        ":protos_perfetto_config_profiling_protos",
+        ":protos_perfetto_config_protos",
+        ":protos_perfetto_config_sys_stats_protos",
+        ":protos_perfetto_trace_android_protos",
+        ":protos_perfetto_trace_appended_data_protos",
+        ":protos_perfetto_trace_chrome_protos",
+        ":protos_perfetto_trace_filesystem_protos",
+        ":protos_perfetto_trace_ftrace_protos",
+        ":protos_perfetto_trace_gpu_protos",
+        ":protos_perfetto_trace_interned_data_protos",
+        ":protos_perfetto_trace_minimal_protos",
+        ":protos_perfetto_trace_perfetto_protos",
+        ":protos_perfetto_trace_power_protos",
+        ":protos_perfetto_trace_profiling_protos",
+        ":protos_perfetto_trace_ps_protos",
+        ":protos_perfetto_trace_sys_stats_protos",
+        ":protos_perfetto_trace_track_event_protos",
+    ],
+)
+
+# ##############################################################################
+# Public targets
+# ##############################################################################
+
+# GN target: //src/perfetto_cmd:perfetto
+perfetto_cc_binary(
+    name = "perfetto",
+    srcs = [
+        "src/perfetto_cmd/main.cc",
+        ":include_perfetto_base_base",
+        ":include_perfetto_ext_base_base",
+        ":include_perfetto_ext_ipc_ipc",
+        ":include_perfetto_ext_traced_traced",
+        ":include_perfetto_ext_tracing_core_core",
+        ":include_perfetto_ext_tracing_ipc_ipc",
+        ":include_perfetto_protozero_protozero",
+        ":include_perfetto_tracing_core_core",
+        ":include_perfetto_tracing_tracing",
+        ":src_android_internal_headers",
+        ":src_android_internal_lazy_library_loader",
+        ":src_base_base",
+        ":src_base_unix_socket",
+        ":src_ipc_ipc",
+        ":src_perfetto_cmd_perfetto_cmd",
+        ":src_perfetto_cmd_trigger_producer",
+        ":src_protozero_protozero",
+        ":src_tracing_common",
+        ":src_tracing_ipc",
+        ":src_tracing_tracing",
+    ],
+    visibility = [
+        "//visibility:public",
+    ],
+    deps = [
+               ":protos_perfetto_common_lite",
+               ":protos_perfetto_common_zero",
+               ":protos_perfetto_config_android_lite",
+               ":protos_perfetto_config_android_zero",
+               ":protos_perfetto_config_ftrace_lite",
+               ":protos_perfetto_config_ftrace_zero",
+               ":protos_perfetto_config_gpu_lite",
+               ":protos_perfetto_config_gpu_zero",
+               ":protos_perfetto_config_inode_file_lite",
+               ":protos_perfetto_config_inode_file_zero",
+               ":protos_perfetto_config_lite",
+               ":protos_perfetto_config_power_lite",
+               ":protos_perfetto_config_power_zero",
+               ":protos_perfetto_config_process_stats_lite",
+               ":protos_perfetto_config_process_stats_zero",
+               ":protos_perfetto_config_profiling_lite",
+               ":protos_perfetto_config_profiling_zero",
+               ":protos_perfetto_config_sys_stats_lite",
+               ":protos_perfetto_config_sys_stats_zero",
+               ":protos_perfetto_config_zero",
+               ":protos_perfetto_ipc_ipc",
+               ":protos_perfetto_ipc_wire_protocol",
+               ":protos_perfetto_trace_android_zero",
+               ":protos_perfetto_trace_appended_data_zero",
+               ":protos_perfetto_trace_chrome_zero",
+               ":protos_perfetto_trace_filesystem_zero",
+               ":protos_perfetto_trace_ftrace_zero",
+               ":protos_perfetto_trace_gpu_zero",
+               ":protos_perfetto_trace_interned_data_zero",
+               ":protos_perfetto_trace_minimal_lite",
+               ":protos_perfetto_trace_minimal_zero",
+               ":protos_perfetto_trace_non_minimal_zero",
+               ":protos_perfetto_trace_perfetto_zero",
+               ":protos_perfetto_trace_power_zero",
+               ":protos_perfetto_trace_profiling_zero",
+               ":protos_perfetto_trace_ps_zero",
+               ":protos_perfetto_trace_sys_stats_zero",
+               ":protos_perfetto_trace_track_event_zero",
+               ":protos_perfetto_trace_trusted_lite",
+               ":src_perfetto_cmd_protos",
+           ] + PERFETTO_CONFIG.deps.zlib +
+           PERFETTO_CONFIG.deps.protobuf_lite,
+)
+
+# GN target: //src/trace_processor:trace_processor
+perfetto_cc_library(
+    name = "trace_processor",
+    srcs = [
+        ":src_base_base",
+        ":src_protozero_protozero",
+        ":src_trace_processor_common",
+        ":src_trace_processor_db_lib",
+        ":src_trace_processor_lib",
+        ":src_trace_processor_metrics_lib",
+        ":src_trace_processor_sqlite_sqlite",
+        ":src_trace_processor_tables_tables",
+    ],
+    hdrs = [
+        ":include_perfetto_base_base",
+        ":include_perfetto_ext_base_base",
+        ":include_perfetto_ext_traced_sys_stats_counters",
+        ":include_perfetto_protozero_protozero",
+        ":include_perfetto_trace_processor_trace_processor",
+    ],
+    visibility = [
+        "//visibility:public",
+    ],
+    deps = [
+               ":protos_perfetto_common_zero",
+               ":protos_perfetto_config_android_zero",
+               ":protos_perfetto_config_ftrace_zero",
+               ":protos_perfetto_config_gpu_zero",
+               ":protos_perfetto_config_inode_file_zero",
+               ":protos_perfetto_config_power_zero",
+               ":protos_perfetto_config_process_stats_zero",
+               ":protos_perfetto_config_profiling_zero",
+               ":protos_perfetto_config_sys_stats_zero",
+               ":protos_perfetto_config_zero",
+               ":protos_perfetto_metrics_android_zero",
+               ":protos_perfetto_metrics_zero",
+               ":protos_perfetto_trace_android_zero",
+               ":protos_perfetto_trace_appended_data_zero",
+               ":protos_perfetto_trace_chrome_zero",
+               ":protos_perfetto_trace_filesystem_zero",
+               ":protos_perfetto_trace_ftrace_zero",
+               ":protos_perfetto_trace_gpu_zero",
+               ":protos_perfetto_trace_interned_data_zero",
+               ":protos_perfetto_trace_minimal_zero",
+               ":protos_perfetto_trace_non_minimal_zero",
+               ":protos_perfetto_trace_perfetto_zero",
+               ":protos_perfetto_trace_power_zero",
+               ":protos_perfetto_trace_processor_metrics_impl_zero",
+               ":protos_perfetto_trace_profiling_zero",
+               ":protos_perfetto_trace_ps_zero",
+               ":protos_perfetto_trace_sys_stats_zero",
+               ":protos_perfetto_trace_track_event_zero",
+           ] + PERFETTO_CONFIG.deps.jsoncpp +
+           PERFETTO_CONFIG.deps.zlib +
+           PERFETTO_CONFIG.deps.sqlite +
+           PERFETTO_CONFIG.deps.sqlite_ext_percentile + [
+               ":cc_merged_sql_metrics"
+    ],
+)
+
+# GN target: //src/trace_processor:trace_processor_shell
+perfetto_cc_binary(
+    name = "trace_processor_shell",
+    srcs = [
+        "src/trace_processor/proto_to_json.cc",
+        "src/trace_processor/proto_to_json.h",
+        "src/trace_processor/trace_processor_shell.cc",
+        ":include_perfetto_base_base",
+        ":include_perfetto_ext_base_base",
+        ":include_perfetto_ext_traced_sys_stats_counters",
+        ":include_perfetto_protozero_protozero",
+        ":include_perfetto_trace_processor_trace_processor",
+        ":src_base_base",
+        ":src_protozero_protozero",
+        ":src_trace_processor_common",
+        ":src_trace_processor_db_lib",
+        ":src_trace_processor_lib",
+        ":src_trace_processor_metrics_lib",
+        ":src_trace_processor_sqlite_sqlite",
+        ":src_trace_processor_tables_tables",
+    ],
+    visibility = [
+        "//visibility:public",
+    ],
+    deps = [
+               ":protos_perfetto_common_zero",
+               ":protos_perfetto_config_android_zero",
+               ":protos_perfetto_config_ftrace_zero",
+               ":protos_perfetto_config_gpu_zero",
+               ":protos_perfetto_config_inode_file_zero",
+               ":protos_perfetto_config_power_zero",
+               ":protos_perfetto_config_process_stats_zero",
+               ":protos_perfetto_config_profiling_zero",
+               ":protos_perfetto_config_sys_stats_zero",
+               ":protos_perfetto_config_zero",
+               ":protos_perfetto_metrics_android_zero",
+               ":protos_perfetto_metrics_zero",
+               ":protos_perfetto_trace_android_zero",
+               ":protos_perfetto_trace_appended_data_zero",
+               ":protos_perfetto_trace_chrome_zero",
+               ":protos_perfetto_trace_filesystem_zero",
+               ":protos_perfetto_trace_ftrace_zero",
+               ":protos_perfetto_trace_gpu_zero",
+               ":protos_perfetto_trace_interned_data_zero",
+               ":protos_perfetto_trace_minimal_zero",
+               ":protos_perfetto_trace_non_minimal_zero",
+               ":protos_perfetto_trace_perfetto_zero",
+               ":protos_perfetto_trace_power_zero",
+               ":protos_perfetto_trace_processor_metrics_impl_zero",
+               ":protos_perfetto_trace_profiling_zero",
+               ":protos_perfetto_trace_ps_zero",
+               ":protos_perfetto_trace_sys_stats_zero",
+               ":protos_perfetto_trace_track_event_zero",
+           ] + PERFETTO_CONFIG.deps.protoc_lib +
+           PERFETTO_CONFIG.deps.linenoise +
+           PERFETTO_CONFIG.deps.jsoncpp +
+           PERFETTO_CONFIG.deps.zlib +
+           PERFETTO_CONFIG.deps.sqlite +
+           PERFETTO_CONFIG.deps.sqlite_ext_percentile + [
+               ":cc_merged_sql_metrics"
+    ],
+)
+
+# GN target: //src/traced/probes:traced_probes
+perfetto_cc_binary(
+    name = "traced_probes",
+    srcs = [
+        "src/traced/probes/main.cc",
+        ":include_perfetto_ext_traced_traced",
+    ],
+    visibility = [
+        "//visibility:public",
+    ],
+    deps = [
+        ":libperfetto",
+    ],
+)
+
+# GN target: //src/traced/service:traced
+perfetto_cc_binary(
+    name = "traced",
+    srcs = [
+        "src/traced/service/main.cc",
+        ":include_perfetto_ext_traced_traced",
+    ],
+    visibility = [
+        "//visibility:public",
+    ],
+    deps = [
+        ":libperfetto",
+    ],
+)
+
+# GN target: //tools/trace_to_text:libpprofbuilder
+perfetto_cc_library(
+    name = "libpprofbuilder",
+    srcs = [
+        ":src_base_base",
+        ":src_protozero_protozero",
+        ":src_trace_processor_common",
+        ":src_trace_processor_db_lib",
+        ":src_trace_processor_lib",
+        ":src_trace_processor_metrics_lib",
+        ":src_trace_processor_sqlite_sqlite",
+        ":src_trace_processor_tables_tables",
+        ":tools_trace_to_text_pprofbuilder",
+        ":tools_trace_to_text_symbolizer",
+        ":tools_trace_to_text_utils",
+    ],
+    hdrs = [
+        ":include_perfetto_base_base",
+        ":include_perfetto_ext_base_base",
+        ":include_perfetto_ext_traced_sys_stats_counters",
+        ":include_perfetto_protozero_protozero",
+        ":include_perfetto_trace_processor_trace_processor",
+    ],
+    visibility = [
+        "//visibility:public",
+    ],
+    deps = [
+        ":protos_perfetto_common_lite",
+        ":protos_perfetto_common_zero",
+        ":protos_perfetto_config_android_lite",
+        ":protos_perfetto_config_android_zero",
+        ":protos_perfetto_config_ftrace_lite",
+        ":protos_perfetto_config_ftrace_zero",
+        ":protos_perfetto_config_gpu_lite",
+        ":protos_perfetto_config_gpu_zero",
+        ":protos_perfetto_config_inode_file_lite",
+        ":protos_perfetto_config_inode_file_zero",
+        ":protos_perfetto_config_lite",
+        ":protos_perfetto_config_power_lite",
+        ":protos_perfetto_config_power_zero",
+        ":protos_perfetto_config_process_stats_lite",
+        ":protos_perfetto_config_process_stats_zero",
+        ":protos_perfetto_config_profiling_lite",
+        ":protos_perfetto_config_profiling_zero",
+        ":protos_perfetto_config_sys_stats_lite",
+        ":protos_perfetto_config_sys_stats_zero",
+        ":protos_perfetto_config_zero",
+        ":protos_perfetto_metrics_android_zero",
+        ":protos_perfetto_metrics_zero",
+        ":protos_perfetto_trace_android_lite",
+        ":protos_perfetto_trace_android_zero",
+        ":protos_perfetto_trace_appended_data_lite",
+        ":protos_perfetto_trace_appended_data_zero",
+        ":protos_perfetto_trace_chrome_lite",
+        ":protos_perfetto_trace_chrome_zero",
+        ":protos_perfetto_trace_filesystem_lite",
+        ":protos_perfetto_trace_filesystem_zero",
+        ":protos_perfetto_trace_ftrace_lite",
+        ":protos_perfetto_trace_ftrace_zero",
+        ":protos_perfetto_trace_gpu_lite",
+        ":protos_perfetto_trace_gpu_zero",
+        ":protos_perfetto_trace_interned_data_lite",
+        ":protos_perfetto_trace_interned_data_zero",
+        ":protos_perfetto_trace_minimal_lite",
+        ":protos_perfetto_trace_minimal_zero",
+        ":protos_perfetto_trace_non_minimal_lite",
+        ":protos_perfetto_trace_non_minimal_zero",
+        ":protos_perfetto_trace_perfetto_lite",
+        ":protos_perfetto_trace_perfetto_zero",
+        ":protos_perfetto_trace_power_lite",
+        ":protos_perfetto_trace_power_zero",
+        ":protos_perfetto_trace_processor_metrics_impl_zero",
+        ":protos_perfetto_trace_profiling_lite",
+        ":protos_perfetto_trace_profiling_zero",
+        ":protos_perfetto_trace_ps_lite",
+        ":protos_perfetto_trace_ps_zero",
+        ":protos_perfetto_trace_sys_stats_lite",
+        ":protos_perfetto_trace_sys_stats_zero",
+        ":protos_perfetto_trace_track_event_lite",
+        ":protos_perfetto_trace_track_event_zero",
+        ":protos_third_party_pprof_lite",
+    ]
+    + PERFETTO_CONFIG.deps.jsoncpp
+    + PERFETTO_CONFIG.deps.zlib
+    + PERFETTO_CONFIG.deps.sqlite
+    + PERFETTO_CONFIG.deps.sqlite_ext_percentile
+    + [ ":cc_merged_sql_metrics" ],
+)
+
+# GN target: //tools/trace_to_text:trace_to_text
+perfetto_cc_binary(
+    name = "trace_to_text",
+    srcs = [
+        ":include_perfetto_base_base",
+        ":include_perfetto_ext_base_base",
+        ":include_perfetto_ext_traced_sys_stats_counters",
+        ":include_perfetto_protozero_protozero",
+        ":include_perfetto_trace_processor_trace_processor",
+        ":src_base_base",
+        ":src_protozero_protozero",
+        ":src_trace_processor_common",
+        ":src_trace_processor_db_lib",
+        ":src_trace_processor_lib",
+        ":src_trace_processor_metrics_lib",
+        ":src_trace_processor_sqlite_sqlite",
+        ":src_trace_processor_tables_tables",
+        ":tools_trace_to_text_common",
+        ":tools_trace_to_text_full",
+        ":tools_trace_to_text_local_symbolizer",
+        ":tools_trace_to_text_pprofbuilder",
+        ":tools_trace_to_text_symbolizer",
+        ":tools_trace_to_text_utils",
+    ],
+    visibility = [
+        "//visibility:public",
+    ],
+    deps = [
+               ":protos_perfetto_common_lite",
+               ":protos_perfetto_common_zero",
+               ":protos_perfetto_config_android_lite",
+               ":protos_perfetto_config_android_zero",
+               ":protos_perfetto_config_ftrace_lite",
+               ":protos_perfetto_config_ftrace_zero",
+               ":protos_perfetto_config_gpu_lite",
+               ":protos_perfetto_config_gpu_zero",
+               ":protos_perfetto_config_inode_file_lite",
+               ":protos_perfetto_config_inode_file_zero",
+               ":protos_perfetto_config_lite",
+               ":protos_perfetto_config_power_lite",
+               ":protos_perfetto_config_power_zero",
+               ":protos_perfetto_config_process_stats_lite",
+               ":protos_perfetto_config_process_stats_zero",
+               ":protos_perfetto_config_profiling_lite",
+               ":protos_perfetto_config_profiling_zero",
+               ":protos_perfetto_config_sys_stats_lite",
+               ":protos_perfetto_config_sys_stats_zero",
+               ":protos_perfetto_config_zero",
+               ":protos_perfetto_metrics_android_zero",
+               ":protos_perfetto_metrics_zero",
+               ":protos_perfetto_trace_android_lite",
+               ":protos_perfetto_trace_android_zero",
+               ":protos_perfetto_trace_appended_data_lite",
+               ":protos_perfetto_trace_appended_data_zero",
+               ":protos_perfetto_trace_chrome_lite",
+               ":protos_perfetto_trace_chrome_zero",
+               ":protos_perfetto_trace_filesystem_lite",
+               ":protos_perfetto_trace_filesystem_zero",
+               ":protos_perfetto_trace_ftrace_lite",
+               ":protos_perfetto_trace_ftrace_zero",
+               ":protos_perfetto_trace_gpu_lite",
+               ":protos_perfetto_trace_gpu_zero",
+               ":protos_perfetto_trace_interned_data_lite",
+               ":protos_perfetto_trace_interned_data_zero",
+               ":protos_perfetto_trace_minimal_lite",
+               ":protos_perfetto_trace_minimal_zero",
+               ":protos_perfetto_trace_non_minimal_lite",
+               ":protos_perfetto_trace_non_minimal_zero",
+               ":protos_perfetto_trace_perfetto_lite",
+               ":protos_perfetto_trace_perfetto_zero",
+               ":protos_perfetto_trace_power_lite",
+               ":protos_perfetto_trace_power_zero",
+               ":protos_perfetto_trace_processor_metrics_impl_zero",
+               ":protos_perfetto_trace_profiling_lite",
+               ":protos_perfetto_trace_profiling_zero",
+               ":protos_perfetto_trace_ps_lite",
+               ":protos_perfetto_trace_ps_zero",
+               ":protos_perfetto_trace_sys_stats_lite",
+               ":protos_perfetto_trace_sys_stats_zero",
+               ":protos_perfetto_trace_track_event_lite",
+               ":protos_perfetto_trace_track_event_zero",
+               ":protos_third_party_pprof_lite",
+           ] + PERFETTO_CONFIG.deps.protobuf_full +
+           PERFETTO_CONFIG.deps.zlib +
+           PERFETTO_CONFIG.deps.jsoncpp +
+           PERFETTO_CONFIG.deps.sqlite +
+           PERFETTO_CONFIG.deps.sqlite_ext_percentile + [
+               ":cc_merged_sql_metrics"
+    ],
+)
+
+# Content from BUILD.extras
+
+build_config_dir_ = "include/perfetto/base/build_configs/bazel"
+
+# Deliberately NOT a perfetto_cc_library, to avoid cyclic deps.
+# This is pulled as a default dep by all targets.
+cc_library(
+    name = "build_config_hdr",
+    hdrs = [build_config_dir_ + "/perfetto_build_flags.h"],
+    includes = [build_config_dir_],
+)
+
+perfetto_cc_library(
+    name = "cc_merged_sql_metrics",
+    hdrs = ["src/trace_processor/metrics/sql_metrics.h"],
+)
+
+perfetto_py_binary(
+    name = "gen_merged_sql_metrics_py",
+    srcs = [
+        "tools/gen_merged_sql_metrics.py",
+    ],
+    main = "tools/gen_merged_sql_metrics.py",
+    python_version = "PY2",
+)
+
+perfetto_java_proto_library(
+    name = "protos_perfetto_metrics_java",
+    deps = [
+        ":protos_perfetto_metrics_protos",
+    ],
+)
+
+perfetto_java_proto_library(
+    name = "protos_perfetto_metrics_android_java",
+    deps = [
+        ":protos_perfetto_metrics_android_protos",
+    ],
+)
+
+perfetto_gensignature_internal_only(
     name = "trace_processor_sig",
     srcs = [
         ":trace_processor_shell",
@@ -1236,12 +2392,3 @@
         "__TRACE_PROCESSOR_SIG_TAG2",
     ],
 )
-
-py_binary(
-    name = "gen_merged_sql_metrics_py",
-    srcs = [
-        "tools/gen_merged_sql_metrics.py",
-    ],
-    main = "tools/gen_merged_sql_metrics.py",
-    python_version = "PY2",
-)
diff --git a/BUILD.extras b/BUILD.extras
index 8a76d28..968de08 100644
--- a/BUILD.extras
+++ b/BUILD.extras
@@ -1,4 +1,42 @@
-gensignature(
+build_config_dir_ = "include/perfetto/base/build_configs/bazel"
+
+# Deliberately NOT a perfetto_cc_library, to avoid cyclic deps.
+# This is pulled as a default dep by all targets.
+cc_library(
+    name = "build_config_hdr",
+    hdrs = [build_config_dir_ + "/perfetto_build_flags.h"],
+    includes = [build_config_dir_],
+)
+
+perfetto_cc_library(
+    name = "cc_merged_sql_metrics",
+    hdrs = ["src/trace_processor/metrics/sql_metrics.h"],
+)
+
+perfetto_py_binary(
+    name = "gen_merged_sql_metrics_py",
+    srcs = [
+        "tools/gen_merged_sql_metrics.py",
+    ],
+    main = "tools/gen_merged_sql_metrics.py",
+    python_version = "PY2",
+)
+
+perfetto_java_proto_library(
+    name = "protos_perfetto_metrics_java",
+    deps = [
+        ":protos_perfetto_metrics_protos",
+    ],
+)
+
+perfetto_java_proto_library(
+    name = "protos_perfetto_metrics_android_java",
+    deps = [
+        ":protos_perfetto_metrics_android_protos",
+    ],
+)
+
+perfetto_gensignature_internal_only(
     name = "trace_processor_sig",
     srcs = [
         ":trace_processor_shell",
@@ -9,12 +47,3 @@
         "__TRACE_PROCESSOR_SIG_TAG2",
     ],
 )
-
-py_binary(
-    name = "gen_merged_sql_metrics_py",
-    srcs = [
-        "tools/gen_merged_sql_metrics.py",
-    ],
-    main = "tools/gen_merged_sql_metrics.py",
-    python_version = "PY2",
-)
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index b491a6e..2278b9a 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -22,7 +22,7 @@
   def long_line_sources(x): return input.FilterSourceFile(
       x, white_list=".*",
       black_list=['Android[.]bp', '.*[.]json$', '.*[.]sql$', '.*[.]out$',
-                  'test/trace_processor/index$', 'BUILD$', 'protos/BUILD$',
+                  'test/trace_processor/index$', '.*\bBUILD$', 'WORKSPACE',
                   '.*/Makefile$', '/perfetto_build_flags.h$'])
   results = []
   results += input.canned_checks.CheckDoNotSubmit(input, output)
diff --git a/WORKSPACE b/WORKSPACE
new file mode 100644
index 0000000..a933c67
--- /dev/null
+++ b/WORKSPACE
@@ -0,0 +1,31 @@
+# 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 used only in standalone builds. This file is ignored both in
+# embedder builds (i.e. when other projects pull perfetto under /third_party/
+# or similar) and in google internal builds.
+
+workspace(name = "perfetto")
+
+new_local_repository(
+    name = "perfetto_cfg",
+    path = "bazel/standalone",
+    build_file_content = ""
+)
+
+load("@perfetto//bazel:deps.bzl", "perfetto_deps")
+perfetto_deps()
+
+load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
+protobuf_deps()
diff --git a/bazel/BUILD b/bazel/BUILD
new file mode 100644
index 0000000..069748d
--- /dev/null
+++ b/bazel/BUILD
@@ -0,0 +1,19 @@
+# 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.
+
+config_setting(
+    name = "os_osx",
+    values = {"cpu": "darwin"},
+    visibility = ["//visibility:public"],
+)
diff --git a/bazel/deps.bzl b/bazel/deps.bzl
new file mode 100644
index 0000000..6f19f3d
--- /dev/null
+++ b/bazel/deps.bzl
@@ -0,0 +1,88 @@
+# 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.
+
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")
+
+# This file must be kept in sync with tools/install-build-deps.
+
+def perfetto_deps():
+    # Note: this is more recent than the version of protobuf we use in the
+    # GN and Android builds. This is because older versions of protobuf don't
+    # support Bazel.
+    _add_repo_if_not_existing(
+        http_archive,
+        name = "com_google_protobuf",
+        strip_prefix = "protobuf-3.9.0",
+        url = "https://github.com/google/protobuf/archive/v3.9.0.tar.gz",
+        sha256 = "2ee9dcec820352671eb83e081295ba43f7a4157181dad549024d7070d079cf65",
+    )
+
+    _add_repo_if_not_existing(
+        http_archive,
+        name = "perfetto_dep_sqlite",
+        url = "https://storage.googleapis.com/perfetto/sqlite-amalgamation-3250300.zip",
+        sha256 = "2ad5379f3b665b60599492cc8a13ac480ea6d819f91b1ef32ed0e1ad152fafef",
+        strip_prefix = "sqlite-amalgamation-3250300",
+        build_file = "//bazel:sqlite.BUILD",
+    )
+
+    _add_repo_if_not_existing(
+        http_archive,
+        name = "perfetto_dep_sqlite_src",
+        url = "https://storage.googleapis.com/perfetto/sqlite-src-3250300.zip",
+        sha256 = "c7922bc840a799481050ee9a76e679462da131adba1814687f05aa5c93766421",
+        strip_prefix = "sqlite-src-3250300",
+        build_file = "//bazel:sqlite.BUILD",
+    )
+
+    _add_repo_if_not_existing(
+        new_git_repository,
+        name = "perfetto_dep_linenoise",
+        remote = "https://fuchsia.googlesource.com/third_party/linenoise.git",
+        commit = "c894b9e59f02203dbe4e2be657572cf88c4230c3",
+        build_file = "//bazel:linenoise.BUILD",
+        shallow_since = "1469784335 +0200",
+    )
+
+    _add_repo_if_not_existing(
+        new_git_repository,
+        name = "perfetto_dep_jsoncpp",
+        remote = "https://github.com/open-source-parsers/jsoncpp",
+        commit = "7165f6ac4c482e68475c9e1dac086f9e12fff0d0",  # v1.0.0
+        build_file = "//bazel:jsoncpp.BUILD",
+        shallow_since = "1416494758 -0600",
+    )
+
+    _add_repo_if_not_existing(
+        new_git_repository,
+        name = "perfetto_dep_zlib",
+        remote = "https://android.googlesource.com/platform/external/zlib.git",
+        commit = "dfa0646a03b4e1707469e04dc931b09774968fe6",
+        build_file = "//bazel:zlib.BUILD",
+        shallow_since = "1557160162 -0700",
+    )
+
+    # Without this protobuf.bzl fails. This seems a bug in protobuf_deps().
+    _add_repo_if_not_existing(
+        http_archive,
+        name = "bazel_skylib",
+        sha256 = "bbccf674aa441c266df9894182d80de104cabd19be98be002f6d478aaa31574d",
+        strip_prefix = "bazel-skylib-2169ae1c374aab4a09aa90e65efe1a3aad4e279b",
+        url = "https://github.com/bazelbuild/bazel-skylib/archive/2169ae1c374aab4a09aa90e65efe1a3aad4e279b.tar.gz",
+    )
+
+def _add_repo_if_not_existing(repo_rule, name, **kwargs):
+    if name not in native.existing_rules():
+        repo_rule(name = name, **kwargs)
diff --git a/bazel/jsoncpp.BUILD b/bazel/jsoncpp.BUILD
new file mode 100644
index 0000000..8a33eb8
--- /dev/null
+++ b/bazel/jsoncpp.BUILD
@@ -0,0 +1,49 @@
+# 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.
+
+cc_library(
+    name = "jsoncpp",
+    srcs = [
+        "src/lib_json/json_batchallocator.h",
+        "src/lib_json/json_internalarray.inl",
+        "src/lib_json/json_internalmap.inl",
+        "src/lib_json/json_reader.cpp",
+        "src/lib_json/json_tool.h",
+        "src/lib_json/json_value.cpp",
+        "src/lib_json/json_valueiterator.inl",
+        "src/lib_json/json_writer.cpp",
+    ],
+    hdrs = [
+        "include/json/assertions.h",
+        "include/json/autolink.h",
+        "include/json/config.h",
+        "include/json/features.h",
+        "include/json/forwards.h",
+        "include/json/json.h",
+        "include/json/reader.h",
+        "include/json/value.h",
+        "include/json/version.h",
+        "include/json/writer.h",
+    ],
+    copts = [
+        "-Isrc/lib_json",
+    ],
+    defines = [
+        "JSON_USE_EXCEPTION=0",
+    ],
+    includes = [
+        "include",
+    ],
+    visibility = ["//visibility:public"],
+)
diff --git a/bazel/linenoise.BUILD b/bazel/linenoise.BUILD
new file mode 100644
index 0000000..d2b6053
--- /dev/null
+++ b/bazel/linenoise.BUILD
@@ -0,0 +1,27 @@
+# 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.
+
+cc_library(
+    name = "linenoise",
+    srcs = [
+        "linenoise.c",
+    ],
+    hdrs = [
+        "linenoise.h",
+    ],
+    includes = [
+        ".",
+    ],
+    visibility = ["//visibility:public"],
+)
diff --git a/bazel/proto_gen.bzl b/bazel/proto_gen.bzl
new file mode 100644
index 0000000..cf0d5ff
--- /dev/null
+++ b/bazel/proto_gen.bzl
@@ -0,0 +1,114 @@
+# 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 defines the proto_gen() rule that is used for generating protos
+# with custom plugins (ipc and protozero).
+
+def _proto_gen_impl(ctx):
+    proto_src = [
+        f
+        for dep in ctx.attr.deps
+        for f in dep[ProtoInfo].direct_sources
+    ]
+    includes = [
+        f
+        for dep in ctx.attr.deps
+        for f in dep[ProtoInfo].transitive_imports.to_list()
+    ]
+
+    proto_path = "."
+
+    out_dir = str(ctx.genfiles_dir.path)
+    strip_base_path = ""
+    if ctx.attr.root != "//":
+        # This path is hit in Google internal builds, where root is typically
+        # //third_party/perfetto.
+        proto_path = "."
+        strip_base_path = ctx.attr.root[2:] + "/"  # -> third_party/perfetto/
+    elif ctx.label.workspace_root:
+        # This path is hit when proto targets are built as @perfetto//:xxx
+        # instead of //:xxx. This happens in embedder builds. In this case,
+        # workspace_root == "external/perfetto" and we need to rebase the paths
+        # passed to protoc.
+        proto_path = ctx.label.workspace_root
+        out_dir += "/" + ctx.label.workspace_root
+        strip_base_path = ctx.label.workspace_root + "/"
+
+    out_files = []
+    suffix = ctx.attr.suffix
+    for src in proto_src:
+        base_path = src.path[:-len(".proto")]
+        if base_path.startswith(strip_base_path):
+            base_path = base_path[len(strip_base_path):]
+        out_files += [ctx.actions.declare_file(base_path + ".%s.h" % suffix)]
+        out_files += [ctx.actions.declare_file(base_path + ".%s.cc" % suffix)]
+
+    arguments = [
+        "--proto_path=" + proto_path,
+    ]
+    plugin_deps = []
+    if ctx.attr.plugin:
+        arguments += [
+            "--plugin=protoc-gen-plugin=" + ctx.executable.plugin.path,
+            "--plugin_out=wrapper_namespace=pbzero:" + out_dir,
+        ]
+        plugin_deps += [ctx.executable.plugin]
+    else:
+        arguments += [
+            "--cpp_out=" + out_dir,
+        ]
+
+    arguments += [src.path for src in proto_src]
+    ctx.actions.run(
+        inputs = proto_src + includes + plugin_deps,
+        tools = plugin_deps,
+        outputs = out_files,
+        executable = ctx.executable.protoc,
+        arguments = arguments,
+    )
+    return [
+        DefaultInfo(files = depset(out_files)),
+        OutputGroupInfo(
+            cc = depset([f for f in out_files if f.path.endswith(".cc")]),
+            h = depset([f for f in out_files if f.path.endswith(".h")]),
+        ),
+    ]
+
+proto_gen = rule(
+    attrs = {
+        "deps": attr.label_list(
+            mandatory = True,
+            allow_empty = False,
+            providers = [ProtoInfo],
+        ),
+        "plugin": attr.label(
+            executable = True,
+            mandatory = False,
+            cfg = "host",
+        ),
+        "suffix": attr.string(
+            mandatory = True,
+        ),
+        "protoc": attr.label(
+            executable = True,
+            cfg = "host",
+        ),
+        "root": attr.string(
+            mandatory = False,
+            default = "//",
+        ),
+    },
+    output_to_genfiles = True,
+    implementation = _proto_gen_impl,
+)
diff --git a/bazel/rules.bzl b/bazel/rules.bzl
new file mode 100644
index 0000000..87c48c7
--- /dev/null
+++ b/bazel/rules.bzl
@@ -0,0 +1,169 @@
+# 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.
+
+load("@perfetto_cfg//:perfetto_cfg.bzl", "PERFETTO_CONFIG")
+load("@perfetto//bazel:proto_gen.bzl", "proto_gen")
+
+# +----------------------------------------------------------------------------+
+# | Base C++ rules.                                                            |
+# +----------------------------------------------------------------------------+
+
+def default_cc_args():
+    return {
+        "deps": [PERFETTO_CONFIG.root + ":build_config_hdr"],
+        "copts": [],
+        "includes": ["include"],
+        "linkopts": select({
+            "@perfetto//bazel:os_osx": [],
+            "//conditions:default": ["-ldl", "-lrt"],
+        }),
+    }
+
+def perfetto_cc_library(**kwargs):
+    args = _merge_dicts(default_cc_args(), kwargs)
+    if not _rule_override("cc_library", **args):
+        native.cc_library(**args)
+
+def perfetto_cc_binary(**kwargs):
+    args = _merge_dicts(default_cc_args(), kwargs)
+    if not _rule_override("cc_binary", **args):
+        native.cc_binary(**args)
+
+def perfetto_py_binary(**kwargs):
+    if not _rule_override("py_binary", **kwargs):
+        native.py_binary(**kwargs)
+
+# +----------------------------------------------------------------------------+
+# | Proto-related rules                                                        |
+# +----------------------------------------------------------------------------+
+
+def perfetto_proto_library(**kwargs):
+    if not _rule_override("proto_library", **kwargs):
+        native.proto_library(**kwargs)
+
+def perfetto_cc_proto_library(**kwargs):
+    if not _rule_override("cc_proto_library", **kwargs):
+        native.cc_proto_library(**kwargs)
+
+def perfetto_java_proto_library(**kwargs):
+    if not _rule_override("java_proto_library", **kwargs):
+        native.java_proto_library(**kwargs)
+
+# +----------------------------------------------------------------------------+
+# | Misc rules.                                                                |
+# +----------------------------------------------------------------------------+
+
+# Unlike all the other rules, this is an noop by default because Bazel does not
+# support gensignature.
+def perfetto_gensignature_internal_only(**kwargs):
+    _rule_override("gensignature_internal_only", **kwargs)
+
+# Generates .pbzero.{cc,h} from .proto(s). We deliberately do NOT generate
+# conventional .pb.{cc,h} from here as protozero gen sources do not have any
+# dependency on libprotobuf.
+def perfetto_cc_protozero_library(name, deps, **kwargs):
+    if _rule_override(
+        "cc_protozero_library",
+        name = name,
+        deps = deps,
+        **kwargs
+    ):
+        return
+
+    proto_gen(
+        name = name + "_src",
+        deps = deps,
+        suffix = "pbzero",
+        plugin = PERFETTO_CONFIG.root + ":protozero_plugin",
+        protoc = PERFETTO_CONFIG.deps.protoc[0],
+        root = PERFETTO_CONFIG.root,
+    )
+
+    native.filegroup(
+        name = name + "_h",
+        srcs = [":" + name + "_src"],
+        output_group = "h",
+    )
+
+    perfetto_cc_library(
+        name = name,
+        srcs = [":" + name + "_src"],
+        hdrs = [":" + name + "_h"],
+        deps = [PERFETTO_CONFIG.root + ":libprotozero"],
+        **kwargs
+    )
+
+# Generates .ipc.{cc,h} and .pb.{cc.h} from .proto(s). The IPC sources depend
+# on .pb.h so we need to generate also the standard protobuf sources here.
+def perfetto_cc_ipc_library(name, deps, **kwargs):
+    if _rule_override("cc_ipc_library", name = name, deps = deps, **kwargs):
+        return
+
+    # Takes care of generating .pb.{cc,h}.
+    perfetto_cc_proto_library(name = name + "_pb", deps = deps)
+
+    # Generates .ipc.{cc,h}.
+    proto_gen(
+        name = name + "_src",
+        deps = deps,
+        suffix = "ipc",
+        plugin = PERFETTO_CONFIG.root + ":ipc_plugin",
+        protoc = PERFETTO_CONFIG.deps.protoc[0],
+        root = PERFETTO_CONFIG.root,
+    )
+
+    native.filegroup(
+        name = name + "_h",
+        srcs = [":" + name + "_src"],
+        output_group = "h",
+    )
+
+    perfetto_cc_library(
+        name = name,
+        srcs = [":" + name + "_src"],
+        hdrs = [":" + name + "_h"],
+        deps = [
+            ":" + name + "_pb",
+
+            # Generated .ipc.{cc,h} depend on this.
+            PERFETTO_CONFIG.root + ":perfetto_ipc",
+
+            # Generated .pb.{cc,h} depend on this.
+        ] + PERFETTO_CONFIG.deps.protobuf_lite,
+        **kwargs
+    )
+
+# +----------------------------------------------------------------------------+
+# | Misc utility functions                                                     |
+# +----------------------------------------------------------------------------+
+
+def _rule_override(rule_name, **kwargs):
+    overrides = getattr(PERFETTO_CONFIG, "rule_overrides", struct())
+    overridden_rule = getattr(overrides, rule_name, None)
+    if overridden_rule:
+        overridden_rule(**kwargs)
+        return True
+    return False
+
+def _merge_dicts(*args):
+    res = {}
+    for arg in args:
+        for k, v in arg.items():
+            if type(v) == "string":
+                res[k] = v
+            elif type(v) == "list" or type(v) == "select":
+                res[k] = res.get(k, []) + v
+            else:
+                fail("key type not supported: " + type(v))
+    return res
diff --git a/bazel/sqlite.BUILD b/bazel/sqlite.BUILD
new file mode 100644
index 0000000..e028f1f
--- /dev/null
+++ b/bazel/sqlite.BUILD
@@ -0,0 +1,78 @@
+# 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 build file is used for both @perfetto_dep_sqlite and
+# @perfetto_dep_sqlite_src.
+
+load("@perfetto_cfg//:perfetto_cfg.bzl", "PERFETTO_CONFIG")
+
+# #############################
+# @perfetto_dep_sqlite section
+# #############################
+
+filegroup(
+    name = "headers",
+    srcs = [
+        "sqlite3.h",
+        "sqlite3ext.h",
+    ],
+    visibility = ["//visibility:public"],
+)
+
+include_sqlite = [
+    ".",
+]
+
+sqlite_copts = [
+    "-DSQLITE_THREADSAFE=0",
+    "-DQLITE_DEFAULT_MEMSTATUS=0",
+    "-DSQLITE_LIKE_DOESNT_MATCH_BLOBS",
+    "-DSQLITE_OMIT_DEPRECATED",
+    "-DSQLITE_OMIT_SHARED_CACHE",
+    "-DHAVE_USLEEP",
+    "-DHAVE_UTIME",
+    "-DSQLITE_BYTEORDER=1234",
+    "-DSQLITE_DEFAULT_AUTOVACUUM=0",
+    "-DSQLITE_DEFAULT_MMAP_SIZE=0",
+    "-DSQLITE_CORE",
+    "-DSQLITE_TEMP_STORE=3",
+    "-DSQLITE_OMIT_LOAD_EXTENSION",
+    "-DSQLITE_OMIT_RANDOMNESS",
+]
+
+cc_library(
+    name = "sqlite",
+    srcs = [
+        "sqlite3.c",
+        "sqlite3.h",
+    ],
+    hdrs = [":headers"],
+    copts = sqlite_copts,
+    includes = include_sqlite,
+    visibility = ["//visibility:public"],
+)
+
+# ################################
+# @perfetto_dep_sqlite_src section
+# ################################
+
+cc_library(
+    name = "percentile_ext",
+    srcs = [
+        "ext/misc/percentile.c",
+    ],
+    copts = sqlite_copts,
+    deps = PERFETTO_CONFIG.deps.sqlite,
+    visibility = ["//visibility:public"],
+)
diff --git a/bazel/standalone/README.md b/bazel/standalone/README.md
new file mode 100644
index 0000000..6b549b3
--- /dev/null
+++ b/bazel/standalone/README.md
@@ -0,0 +1,25 @@
+# Perfetto standalone Bazel config
+
+This directory is only used in standalone builds.
+The WORKSPACE aliases this directory to @perfetto_cfg.
+
+Bazel-based embedders are supposed to:
+
+### 1. Have a (modified) copy of perfetto_cfg.bzl in their repo
+
+```
+myproject/
+  build/
+    perfetto_overrides/
+      perfetto_cfg.bzl
+```
+
+### 2. Have a repository rule that maps the directory to @perfetto_cfg
+
+E.g in myproject/WORKSPACE
+```
+local_repository(
+    name = "perfetto_cfg",
+    path = "build/perfetto_overrides",
+)
+```
diff --git a/bazel/standalone/perfetto_cfg.bzl b/bazel/standalone/perfetto_cfg.bzl
new file mode 100644
index 0000000..e89c7a0
--- /dev/null
+++ b/bazel/standalone/perfetto_cfg.bzl
@@ -0,0 +1,62 @@
+# 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.
+
+# Noop function used to override rules we don't want to support in standalone.
+def _noop_override(**kwargs):
+    pass
+
+PERFETTO_CONFIG = struct(
+    # This is used to refer to deps within perfetto's BUILD files.
+    # In standalone and bazel-based embedders use '//', because perfetto has its
+    # own repository, and //xxx would be relative to @perfetto//xxx.
+    # In Google internal builds, instead, this is set to //third_party/perfetto,
+    # because perfetto doesn't have its own repository there.
+    root = "//",
+
+    # These variables map dependencies to perfetto third-party projects. This is
+    # to allow perfetto embedders (e.g. gapid) and google internal builds to
+    # override paths and target names to their own third_party.
+    deps = struct(
+        zlib = ["@perfetto_dep_zlib//:zlib"],
+        jsoncpp = ["@perfetto_dep_jsoncpp//:jsoncpp"],
+        linenoise = ["@perfetto_dep_linenoise//:linenoise"],
+        sqlite = ["@perfetto_dep_sqlite//:sqlite"],
+        sqlite_ext_percentile = ["@perfetto_dep_sqlite_src//:percentile_ext"],
+        protoc = ["@com_google_protobuf//:protoc"],
+        protoc_lib = ["@com_google_protobuf//:protoc_lib"],
+        protobuf_lite = ["@com_google_protobuf//:protobuf_lite"],
+        protobuf_full = ["@com_google_protobuf//:protobuf"],
+    ),
+
+    # This struct allows the embedder to customize copts and other args passed
+    # to rules like cc_binary. Prefixed rules (e.g. perfetto_cc_binary) will
+    # look into this struct before falling back on native.cc_binary().
+    # This field is completely optional, the embedder can omit the whole
+    # |rule_overrides| or invidivual keys. They are assigned to None or noop
+    # actions here just for documentation purposes.
+    rule_overrides = struct(
+        cc_binary = None,
+        cc_library = None,
+        cc_proto_library = None,
+        # Supporting java rules pulls in the JDK and generally is not something
+        # we need for most embedders.
+        java_proto_library = _noop_override,
+        proto_library = None,
+        py_binary = None,
+
+        # We only need this for internal binaries. No other embeedder should
+        # care about this.
+        gensignature_internal_only = None,
+    ),
+)
diff --git a/bazel/zlib.BUILD b/bazel/zlib.BUILD
new file mode 100644
index 0000000..1557352
--- /dev/null
+++ b/bazel/zlib.BUILD
@@ -0,0 +1,54 @@
+# 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.
+
+cc_library(
+    name = "zlib",
+    srcs = [
+        "src/adler32.c",
+        "src/compress.c",
+        "src/crc32.c",
+        "src/crc32.h",
+        "src/deflate.c",
+        "src/deflate.h",
+        "src/gzclose.c",
+        "src/gzguts.h",
+        "src/gzlib.c",
+        "src/gzread.c",
+        "src/gzwrite.c",
+        "src/infback.c",
+        "src/inffast.c",
+        "src/inffast.h",
+        "src/inffixed.h",
+        "src/inflate.c",
+        "src/inflate.h",
+        "src/inftrees.c",
+        "src/inftrees.h",
+        "src/trees.c",
+        "src/trees.h",
+        "src/uncompr.c",
+        "src/zconf.h",
+        "src/zlib.h",
+        "src/zutil.c",
+        "src/zutil.h",
+    ],
+    hdrs = [
+        "zlib.h",
+    ],
+    copts = [
+        "-DHAVE_HIDDEN",
+        "-Isrc",
+    ],
+    includes = ["zlib"],
+    visibility = ["//visibility:public"],
+)
diff --git a/docs/metrics.md b/docs/metrics.md
index b2db697..6f4079b 100644
--- a/docs/metrics.md
+++ b/docs/metrics.md
@@ -164,12 +164,12 @@
    is the `dur` - short for duration, this is the amount of time the slice
    lasted - and the `utid` which will be use to join with the thread table.
 2. The next table is the thread table. This gives us a lot of information which
-   are not particularily interested (including its thread name) but it does give
+   are not particularly interested (including its thread name) but it does give
    us the `upid`. Similar to `utid`, `upid` is the unique identifier for a
    process in a Perfetto trace. In this case, `upid` will refer to the process
    which hosts the thread given by `utid`.
 3. The final table is the process table. This gives the name of the
-   process associated with the orginal sched slice.
+   process associated with the original sched slice.
 4. With the process, thread and duration for each sched slice, all the slices
    for a single processes are collected and their durations summed to get the
    CPU time (dividing by 1e6 as sched's duration is in nanoseconds) and count
@@ -218,7 +218,7 @@
    Therefore, the output of this whole SELECT statement is an array of
    5 ProcessInfo protos.
 2. Next is creation of the `TopProcesses` proto. By now, the syntax should
-   already feel somewhat familiar; the proto builder funciton is called
+   already feel somewhat familiar; the proto builder function is called
    to fill in the `process_info` field with the array of protos from the
    inner funciton.
 
diff --git a/gn/BUILD.gn b/gn/BUILD.gn
index a8aecc1..eabbce9 100644
--- a/gn/BUILD.gn
+++ b/gn/BUILD.gn
@@ -215,7 +215,7 @@
 }
 
 # The Google C++ Benchmark library.
-# Only avilable in standalone builds.
+# Only available in standalone builds.
 if (enable_perfetto_benchmarks) {
   group("benchmark") {
     testonly = true
@@ -271,7 +271,7 @@
 
 if (enable_perfetto_trace_processor_linenoise) {
   # Used by the trace_processor_shell for REPL history.
-  # Only avilable in standalone builds.
+  # Only available in standalone builds.
   group("linenoise") {
     public_deps = [
       "//buildtools:linenoise",
diff --git a/gn/perfetto_benchmarks.gni b/gn/perfetto_benchmarks.gni
index 8b6d87e..d5668d6 100644
--- a/gn/perfetto_benchmarks.gni
+++ b/gn/perfetto_benchmarks.gni
@@ -17,6 +17,7 @@
 perfetto_benchmarks_targets = [
   "gn:default_deps",
   "src/traced/probes/ftrace:benchmarks",
+  "src/trace_processor/db:benchmarks",
   "src/tracing:benchmarks",
   "test:benchmark_main",
   "test:end_to_end_benchmarks",
diff --git a/include/perfetto/ext/base/metatrace.h b/include/perfetto/ext/base/metatrace.h
index ceb4bfb..3858f68 100644
--- a/include/perfetto/ext/base/metatrace.h
+++ b/include/perfetto/ext/base/metatrace.h
@@ -68,7 +68,7 @@
 extern std::atomic<uint64_t> g_enabled_timestamp;
 
 // Enables meta-tracing for one or more tags. Once enabled it will discard any
-// futher Enable() calls and return false until disabled,
+// 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
diff --git a/include/perfetto/ext/base/optional.h b/include/perfetto/ext/base/optional.h
index 2a09bf2..b093510 100644
--- a/include/perfetto/ext/base/optional.h
+++ b/include/perfetto/ext/base/optional.h
@@ -44,7 +44,7 @@
 // http://en.cppreference.com/w/cpp/utility/optional/nullopt
 constexpr nullopt_t nullopt(0);
 
-// Forward declaration, which is refered by following helpers.
+// Forward declaration, which is referred by following helpers.
 template <typename T>
 class Optional;
 
diff --git a/include/perfetto/ext/ipc/host.h b/include/perfetto/ext/ipc/host.h
index 2c02c29..bbf3657 100644
--- a/include/perfetto/ext/ipc/host.h
+++ b/include/perfetto/ext/ipc/host.h
@@ -52,10 +52,11 @@
 
   // 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 suceeds and returns true, or immediately
+  // Host instance if ExposeService succeeds and returns true, or immediately
   // after the call in case of failure.
-  // Returns true if the register has been succesfully registered, false in case
-  // of errors (e.g., another service with the same name is already registered).
+  // 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;
 };
 
diff --git a/include/perfetto/protozero/packed_repeated_fields.h b/include/perfetto/protozero/packed_repeated_fields.h
index ed480d5..9d46196 100644
--- a/include/perfetto/protozero/packed_repeated_fields.h
+++ b/include/perfetto/protozero/packed_repeated_fields.h
@@ -59,6 +59,11 @@
     write_ptr_ = proto_utils::WriteVarInt(value, write_ptr_);
   }
 
+  void Reset() {
+    write_ptr_ = storage_begin_;
+    element_size_ = 0;
+  }
+
   const uint8_t* data() const { return storage_begin_; }
 
   size_t size() const {
@@ -94,6 +99,8 @@
     *(write_ptr_++) = value;
   }
 
+  void Reset() { write_ptr_ = storage_begin_; }
+
   const uint8_t* data() const {
     return reinterpret_cast<const uint8_t*>(storage_begin_);
   }
diff --git a/include/perfetto/trace_processor/basic_types.h b/include/perfetto/trace_processor/basic_types.h
index 7b29427..8bd946d 100644
--- a/include/perfetto/trace_processor/basic_types.h
+++ b/include/perfetto/trace_processor/basic_types.h
@@ -66,8 +66,8 @@
 
   int Compare(const SqlValue& value) const {
     // TODO(lalitm): this is almost the same as what SQLite does with the
-    // exception of comparisions between long and double - we choose (for
-    // performance reasons) to omit comparisions between them.
+    // exception of comparisons between long and double - we choose (for
+    // performance reasons) to omit comparisons between them.
     if (type != value.type)
       return type - value.type;
 
diff --git a/include/perfetto/trace_processor/trace_processor.h b/include/perfetto/trace_processor/trace_processor.h
index 0b879f8..17de83b 100644
--- a/include/perfetto/trace_processor/trace_processor.h
+++ b/include/perfetto/trace_processor/trace_processor.h
@@ -53,7 +53,7 @@
     bool Next();
 
     // Returns the value associated with the column |col|. Any call to
-    // |Get()| must be preceeded by a call to |Next()| returning
+    // |Get()| must be preceded by a call to |Next()| returning
     // kHasNext. |col| must be less than the number returned by |ColumnCount()|.
     SqlValue Get(uint32_t col);
 
diff --git a/include/perfetto/tracing.h b/include/perfetto/tracing.h
index 1243c2a..3a4f7d5 100644
--- a/include/perfetto/tracing.h
+++ b/include/perfetto/tracing.h
@@ -18,7 +18,7 @@
 #define INCLUDE_PERFETTO_TRACING_H_
 
 // This headers wraps all the headers necessary to use the public Perfetto
-// Tracing API. Embedders should preferrably use this one header to avoid having
+// 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.
diff --git a/protos/BUILD b/protos/BUILD
deleted file mode 100644
index 25b1514..0000000
--- a/protos/BUILD
+++ /dev/null
@@ -1,1920 +0,0 @@
-# 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 tools/gen_bazel. Do not edit.
-
-load("//tools/build_defs/proto/cpp:cc_proto_library.bzl", "cc_proto_library")
-load("//tools/build_defs/proto:descriptor_set.bzl", "transitive_descriptor_set")
-load("//third_party/perfetto/google:build_defs.bzl", "pbzero_cc_proto_library")
-
-package(default_visibility = ["//third_party/perfetto:__subpackages__"])
-
-licenses(["notice"])  # Apache 2.0
-
-exports_files(["LICENSE"])
-
-# GN target: //protos/perfetto/common:lite_gen
-proto_library(
-    name = "common",
-    srcs = [
-        "perfetto/common/android_log_constants.proto",
-        "perfetto/common/commit_data_request.proto",
-        "perfetto/common/data_source_descriptor.proto",
-        "perfetto/common/descriptor.proto",
-        "perfetto/common/gpu_counter_descriptor.proto",
-        "perfetto/common/observable_events.proto",
-        "perfetto/common/sys_stats_counters.proto",
-        "perfetto/common/trace_stats.proto",
-        "perfetto/common/tracing_service_state.proto",
-        "perfetto/common/track_event_descriptor.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/perfetto/common:lite_gen
-cc_proto_library(
-    name = "common_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:common",
-    ],
-)
-
-# GN target: //protos/perfetto/common:lite_gen
-java_proto_library(
-    name = "common_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:common",
-    ],
-)
-
-# GN target: //protos/perfetto/common:zero_gen
-proto_library(
-    name = "common_zero",
-    srcs = [
-        "perfetto/common/android_log_constants.proto",
-        "perfetto/common/commit_data_request.proto",
-        "perfetto/common/data_source_descriptor.proto",
-        "perfetto/common/descriptor.proto",
-        "perfetto/common/gpu_counter_descriptor.proto",
-        "perfetto/common/observable_events.proto",
-        "perfetto/common/sys_stats_counters.proto",
-        "perfetto/common/trace_stats.proto",
-        "perfetto/common/tracing_service_state.proto",
-        "perfetto/common/track_event_descriptor.proto",
-    ],
-)
-
-# GN target: //protos/perfetto/common:zero_gen
-pbzero_cc_proto_library(
-    name = "common_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:common_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/config:lite_gen
-proto_library(
-    name = "config",
-    srcs = [
-        "perfetto/config/chrome/chrome_config.proto",
-        "perfetto/config/data_source_config.proto",
-        "perfetto/config/test_config.proto",
-        "perfetto/config/trace_config.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:common",
-        "//third_party/perfetto/protos:config_android",
-        "//third_party/perfetto/protos:config_ftrace",
-        "//third_party/perfetto/protos:config_gpu",
-        "//third_party/perfetto/protos:config_inode_file",
-        "//third_party/perfetto/protos:config_power",
-        "//third_party/perfetto/protos:config_process_stats",
-        "//third_party/perfetto/protos:config_profiling",
-        "//third_party/perfetto/protos:config_sys_stats",
-    ],
-)
-
-# GN target: //protos/perfetto/config/android:lite_gen
-proto_library(
-    name = "config_android",
-    srcs = [
-        "perfetto/config/android/android_log_config.proto",
-        "perfetto/config/android/packages_list_config.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:common",
-    ],
-)
-
-# GN target: //protos/perfetto/config/android:lite_gen
-cc_proto_library(
-    name = "config_android_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config_android",
-    ],
-)
-
-# GN target: //protos/perfetto/config/android:lite_gen
-java_proto_library(
-    name = "config_android_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config_android",
-    ],
-)
-
-# GN target: //protos/perfetto/config/android:zero_gen
-proto_library(
-    name = "config_android_zero",
-    srcs = [
-        "perfetto/config/android/android_log_config.proto",
-        "perfetto/config/android/packages_list_config.proto",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:common_zero",
-    ],
-)
-
-# GN target: //protos/perfetto/config/android:zero_gen
-pbzero_cc_proto_library(
-    name = "config_android_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:config_android_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/config:lite_gen
-cc_proto_library(
-    name = "config_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config",
-    ],
-)
-
-# GN target: //protos/perfetto/config/ftrace:lite_gen
-proto_library(
-    name = "config_ftrace",
-    srcs = [
-        "perfetto/config/ftrace/ftrace_config.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/perfetto/config/ftrace:lite_gen
-cc_proto_library(
-    name = "config_ftrace_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config_ftrace",
-    ],
-)
-
-# GN target: //protos/perfetto/config/ftrace:lite_gen
-java_proto_library(
-    name = "config_ftrace_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config_ftrace",
-    ],
-)
-
-# GN target: //protos/perfetto/config/ftrace:zero_gen
-proto_library(
-    name = "config_ftrace_zero",
-    srcs = [
-        "perfetto/config/ftrace/ftrace_config.proto",
-    ],
-)
-
-# GN target: //protos/perfetto/config/ftrace:zero_gen
-pbzero_cc_proto_library(
-    name = "config_ftrace_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:config_ftrace_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/config/gpu:lite_gen
-proto_library(
-    name = "config_gpu",
-    srcs = [
-        "perfetto/config/gpu/gpu_counter_config.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/perfetto/config/gpu:lite_gen
-cc_proto_library(
-    name = "config_gpu_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config_gpu",
-    ],
-)
-
-# GN target: //protos/perfetto/config/gpu:lite_gen
-java_proto_library(
-    name = "config_gpu_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config_gpu",
-    ],
-)
-
-# GN target: //protos/perfetto/config/gpu:zero_gen
-proto_library(
-    name = "config_gpu_zero",
-    srcs = [
-        "perfetto/config/gpu/gpu_counter_config.proto",
-    ],
-)
-
-# GN target: //protos/perfetto/config/gpu:zero_gen
-pbzero_cc_proto_library(
-    name = "config_gpu_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:config_gpu_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/config/inode_file:lite_gen
-proto_library(
-    name = "config_inode_file",
-    srcs = [
-        "perfetto/config/inode_file/inode_file_config.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/perfetto/config/inode_file:lite_gen
-cc_proto_library(
-    name = "config_inode_file_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config_inode_file",
-    ],
-)
-
-# GN target: //protos/perfetto/config/inode_file:lite_gen
-java_proto_library(
-    name = "config_inode_file_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config_inode_file",
-    ],
-)
-
-# GN target: //protos/perfetto/config/inode_file:zero_gen
-proto_library(
-    name = "config_inode_file_zero",
-    srcs = [
-        "perfetto/config/inode_file/inode_file_config.proto",
-    ],
-)
-
-# GN target: //protos/perfetto/config/inode_file:zero_gen
-pbzero_cc_proto_library(
-    name = "config_inode_file_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:config_inode_file_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/config:lite_gen
-java_proto_library(
-    name = "config_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config",
-    ],
-)
-
-# GN target: //protos/perfetto/config:merged_config_gen
-proto_library(
-    name = "config_merged_config_gen",
-    srcs = [
-        "perfetto/config/perfetto_config.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/perfetto/config:merged_config_gen
-cc_proto_library(
-    name = "config_merged_config_gen_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config_merged_config_gen",
-    ],
-)
-
-# GN target: //protos/perfetto/config:merged_config_gen
-java_proto_library(
-    name = "config_merged_config_gen_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config_merged_config_gen",
-    ],
-)
-
-# GN target: //protos/perfetto/config/power:lite_gen
-proto_library(
-    name = "config_power",
-    srcs = [
-        "perfetto/config/power/android_power_config.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/perfetto/config/power:lite_gen
-cc_proto_library(
-    name = "config_power_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config_power",
-    ],
-)
-
-# GN target: //protos/perfetto/config/power:lite_gen
-java_proto_library(
-    name = "config_power_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config_power",
-    ],
-)
-
-# GN target: //protos/perfetto/config/power:zero_gen
-proto_library(
-    name = "config_power_zero",
-    srcs = [
-        "perfetto/config/power/android_power_config.proto",
-    ],
-)
-
-# GN target: //protos/perfetto/config/power:zero_gen
-pbzero_cc_proto_library(
-    name = "config_power_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:config_power_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/config/process_stats:lite_gen
-proto_library(
-    name = "config_process_stats",
-    srcs = [
-        "perfetto/config/process_stats/process_stats_config.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/perfetto/config/process_stats:lite_gen
-cc_proto_library(
-    name = "config_process_stats_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config_process_stats",
-    ],
-)
-
-# GN target: //protos/perfetto/config/process_stats:lite_gen
-java_proto_library(
-    name = "config_process_stats_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config_process_stats",
-    ],
-)
-
-# GN target: //protos/perfetto/config/process_stats:zero_gen
-proto_library(
-    name = "config_process_stats_zero",
-    srcs = [
-        "perfetto/config/process_stats/process_stats_config.proto",
-    ],
-)
-
-# GN target: //protos/perfetto/config/process_stats:zero_gen
-pbzero_cc_proto_library(
-    name = "config_process_stats_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:config_process_stats_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/config/profiling:lite_gen
-proto_library(
-    name = "config_profiling",
-    srcs = [
-        "perfetto/config/profiling/heapprofd_config.proto",
-        "perfetto/config/profiling/java_hprof_config.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/perfetto/config/profiling:lite_gen
-cc_proto_library(
-    name = "config_profiling_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config_profiling",
-    ],
-)
-
-# GN target: //protos/perfetto/config/profiling:lite_gen
-java_proto_library(
-    name = "config_profiling_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config_profiling",
-    ],
-)
-
-# GN target: //protos/perfetto/config/profiling:zero_gen
-proto_library(
-    name = "config_profiling_zero",
-    srcs = [
-        "perfetto/config/profiling/heapprofd_config.proto",
-        "perfetto/config/profiling/java_hprof_config.proto",
-    ],
-)
-
-# GN target: //protos/perfetto/config/profiling:zero_gen
-pbzero_cc_proto_library(
-    name = "config_profiling_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:config_profiling_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/config/sys_stats:lite_gen
-proto_library(
-    name = "config_sys_stats",
-    srcs = [
-        "perfetto/config/sys_stats/sys_stats_config.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:common",
-    ],
-)
-
-# GN target: //protos/perfetto/config/sys_stats:lite_gen
-cc_proto_library(
-    name = "config_sys_stats_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config_sys_stats",
-    ],
-)
-
-# GN target: //protos/perfetto/config/sys_stats:lite_gen
-java_proto_library(
-    name = "config_sys_stats_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:config_sys_stats",
-    ],
-)
-
-# GN target: //protos/perfetto/config/sys_stats:zero_gen
-proto_library(
-    name = "config_sys_stats_zero",
-    srcs = [
-        "perfetto/config/sys_stats/sys_stats_config.proto",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:common_zero",
-    ],
-)
-
-# GN target: //protos/perfetto/config/sys_stats:zero_gen
-pbzero_cc_proto_library(
-    name = "config_sys_stats_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:config_sys_stats_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/config:zero_gen
-proto_library(
-    name = "config_zero",
-    srcs = [
-        "perfetto/config/chrome/chrome_config.proto",
-        "perfetto/config/data_source_config.proto",
-        "perfetto/config/test_config.proto",
-        "perfetto/config/trace_config.proto",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:common_zero",
-        "//third_party/perfetto/protos:config_android_zero",
-        "//third_party/perfetto/protos:config_ftrace_zero",
-        "//third_party/perfetto/protos:config_gpu_zero",
-        "//third_party/perfetto/protos:config_inode_file_zero",
-        "//third_party/perfetto/protos:config_power_zero",
-        "//third_party/perfetto/protos:config_process_stats_zero",
-        "//third_party/perfetto/protos:config_profiling_zero",
-        "//third_party/perfetto/protos:config_sys_stats_zero",
-    ],
-)
-
-# GN target: //protos/perfetto/config:zero_gen
-pbzero_cc_proto_library(
-    name = "config_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:config_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/metrics:lite_gen
-proto_library(
-    name = "metrics",
-    srcs = [
-        "perfetto/metrics/metrics.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:metrics_android",
-    ],
-)
-
-# GN target: //protos/perfetto/metrics/android:lite_gen
-proto_library(
-    name = "metrics_android",
-    srcs = [
-        "perfetto/metrics/android/batt_metric.proto",
-        "perfetto/metrics/android/cpu_metric.proto",
-        "perfetto/metrics/android/heap_profile_callsite_stats.proto",
-        "perfetto/metrics/android/ion_metric.proto",
-        "perfetto/metrics/android/lmk_metric.proto",
-        "perfetto/metrics/android/mem_metric.proto",
-        "perfetto/metrics/android/mem_unagg_metric.proto",
-        "perfetto/metrics/android/package_list.proto",
-        "perfetto/metrics/android/powrails_metric.proto",
-        "perfetto/metrics/android/process_growth.proto",
-        "perfetto/metrics/android/startup_metric.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/perfetto/metrics/android:lite_gen
-cc_proto_library(
-    name = "metrics_android_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:metrics_android",
-    ],
-)
-
-# GN target: //protos/perfetto/metrics/android:lite_gen
-java_proto_library(
-    name = "metrics_android_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:metrics_android",
-    ],
-)
-
-# GN target: //protos/perfetto/metrics/android:zero_gen
-proto_library(
-    name = "metrics_android_zero",
-    srcs = [
-        "perfetto/metrics/android/batt_metric.proto",
-        "perfetto/metrics/android/cpu_metric.proto",
-        "perfetto/metrics/android/heap_profile_callsite_stats.proto",
-        "perfetto/metrics/android/ion_metric.proto",
-        "perfetto/metrics/android/lmk_metric.proto",
-        "perfetto/metrics/android/mem_metric.proto",
-        "perfetto/metrics/android/mem_unagg_metric.proto",
-        "perfetto/metrics/android/package_list.proto",
-        "perfetto/metrics/android/powrails_metric.proto",
-        "perfetto/metrics/android/process_growth.proto",
-        "perfetto/metrics/android/startup_metric.proto",
-    ],
-)
-
-# GN target: //protos/perfetto/metrics/android:zero_gen
-pbzero_cc_proto_library(
-    name = "metrics_android_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:metrics_android_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/metrics:lite_gen
-cc_proto_library(
-    name = "metrics_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:metrics",
-    ],
-)
-
-# GN target: //protos/perfetto/metrics:lite_gen
-java_proto_library(
-    name = "metrics_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:metrics",
-    ],
-)
-
-# GN target: //protos/perfetto/metrics:zero_gen
-proto_library(
-    name = "metrics_zero",
-    srcs = [
-        "perfetto/metrics/metrics.proto",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:metrics_android_zero",
-    ],
-)
-
-# GN target: //protos/perfetto/metrics:zero_gen
-pbzero_cc_proto_library(
-    name = "metrics_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:metrics_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/third_party/pprof:lite_gen
-proto_library(
-    name = "protos_third_party_pprof",
-    srcs = [
-        "third_party/pprof/profile.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/third_party/pprof:lite_gen
-cc_proto_library(
-    name = "protos_third_party_pprof_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:protos_third_party_pprof",
-    ],
-)
-
-# GN target: //protos/third_party/pprof:lite_gen
-java_proto_library(
-    name = "protos_third_party_pprof_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:protos_third_party_pprof",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/android:lite_gen
-proto_library(
-    name = "trace_android",
-    srcs = [
-        "perfetto/trace/android/android_log.proto",
-        "perfetto/trace/android/graphics_frame_event.proto",
-        "perfetto/trace/android/packages_list.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:common",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/android:lite_gen
-cc_proto_library(
-    name = "trace_android_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_android",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/android:lite_gen
-java_proto_library(
-    name = "trace_android_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_android",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/android:zero_gen
-proto_library(
-    name = "trace_android_zero",
-    srcs = [
-        "perfetto/trace/android/android_log.proto",
-        "perfetto/trace/android/graphics_frame_event.proto",
-        "perfetto/trace/android/packages_list.proto",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:common_zero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/android:zero_gen
-pbzero_cc_proto_library(
-    name = "trace_android_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:trace_android_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/appended_data:lite_gen
-proto_library(
-    name = "trace_appended_data",
-    srcs = [
-        "perfetto/trace/appended_data/appended_data.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_profiling",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/appended_data:lite_gen
-cc_proto_library(
-    name = "trace_appended_data_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_appended_data",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/appended_data:lite_gen
-java_proto_library(
-    name = "trace_appended_data_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_appended_data",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/appended_data:zero_gen
-proto_library(
-    name = "trace_appended_data_zero",
-    srcs = [
-        "perfetto/trace/appended_data/appended_data.proto",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_profiling_zero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/appended_data:zero_gen
-pbzero_cc_proto_library(
-    name = "trace_appended_data_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:trace_appended_data_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/chrome:lite_gen
-proto_library(
-    name = "trace_chrome",
-    srcs = [
-        "perfetto/trace/chrome/chrome_benchmark_metadata.proto",
-        "perfetto/trace/chrome/chrome_metadata.proto",
-        "perfetto/trace/chrome/chrome_trace_event.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/chrome:lite_gen
-cc_proto_library(
-    name = "trace_chrome_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_chrome",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/chrome:lite_gen
-java_proto_library(
-    name = "trace_chrome_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_chrome",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/chrome:zero_gen
-proto_library(
-    name = "trace_chrome_zero",
-    srcs = [
-        "perfetto/trace/chrome/chrome_benchmark_metadata.proto",
-        "perfetto/trace/chrome/chrome_metadata.proto",
-        "perfetto/trace/chrome/chrome_trace_event.proto",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/chrome:zero_gen
-pbzero_cc_proto_library(
-    name = "trace_chrome_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:trace_chrome_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/filesystem:lite_gen
-proto_library(
-    name = "trace_filesystem",
-    srcs = [
-        "perfetto/trace/filesystem/inode_file_map.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/filesystem:lite_gen
-cc_proto_library(
-    name = "trace_filesystem_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_filesystem",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/filesystem:lite_gen
-java_proto_library(
-    name = "trace_filesystem_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_filesystem",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/filesystem:zero_gen
-proto_library(
-    name = "trace_filesystem_zero",
-    srcs = [
-        "perfetto/trace/filesystem/inode_file_map.proto",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/filesystem:zero_gen
-pbzero_cc_proto_library(
-    name = "trace_filesystem_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:trace_filesystem_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/ftrace:lite_gen
-proto_library(
-    name = "trace_ftrace",
-    srcs = [
-        "perfetto/trace/ftrace/binder.proto",
-        "perfetto/trace/ftrace/block.proto",
-        "perfetto/trace/ftrace/cgroup.proto",
-        "perfetto/trace/ftrace/clk.proto",
-        "perfetto/trace/ftrace/compaction.proto",
-        "perfetto/trace/ftrace/ext4.proto",
-        "perfetto/trace/ftrace/f2fs.proto",
-        "perfetto/trace/ftrace/fence.proto",
-        "perfetto/trace/ftrace/filemap.proto",
-        "perfetto/trace/ftrace/ftrace.proto",
-        "perfetto/trace/ftrace/ftrace_event.proto",
-        "perfetto/trace/ftrace/ftrace_event_bundle.proto",
-        "perfetto/trace/ftrace/ftrace_stats.proto",
-        "perfetto/trace/ftrace/generic.proto",
-        "perfetto/trace/ftrace/i2c.proto",
-        "perfetto/trace/ftrace/ipi.proto",
-        "perfetto/trace/ftrace/irq.proto",
-        "perfetto/trace/ftrace/kmem.proto",
-        "perfetto/trace/ftrace/lowmemorykiller.proto",
-        "perfetto/trace/ftrace/mdss.proto",
-        "perfetto/trace/ftrace/mm_event.proto",
-        "perfetto/trace/ftrace/oom.proto",
-        "perfetto/trace/ftrace/power.proto",
-        "perfetto/trace/ftrace/raw_syscalls.proto",
-        "perfetto/trace/ftrace/regulator.proto",
-        "perfetto/trace/ftrace/sched.proto",
-        "perfetto/trace/ftrace/signal.proto",
-        "perfetto/trace/ftrace/sync.proto",
-        "perfetto/trace/ftrace/systrace.proto",
-        "perfetto/trace/ftrace/task.proto",
-        "perfetto/trace/ftrace/test_bundle_wrapper.proto",
-        "perfetto/trace/ftrace/vmscan.proto",
-        "perfetto/trace/ftrace/workqueue.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/ftrace:lite_gen
-cc_proto_library(
-    name = "trace_ftrace_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_ftrace",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/ftrace:lite_gen
-java_proto_library(
-    name = "trace_ftrace_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_ftrace",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/ftrace:zero_gen
-proto_library(
-    name = "trace_ftrace_zero",
-    srcs = [
-        "perfetto/trace/ftrace/binder.proto",
-        "perfetto/trace/ftrace/block.proto",
-        "perfetto/trace/ftrace/cgroup.proto",
-        "perfetto/trace/ftrace/clk.proto",
-        "perfetto/trace/ftrace/compaction.proto",
-        "perfetto/trace/ftrace/ext4.proto",
-        "perfetto/trace/ftrace/f2fs.proto",
-        "perfetto/trace/ftrace/fence.proto",
-        "perfetto/trace/ftrace/filemap.proto",
-        "perfetto/trace/ftrace/ftrace.proto",
-        "perfetto/trace/ftrace/ftrace_event.proto",
-        "perfetto/trace/ftrace/ftrace_event_bundle.proto",
-        "perfetto/trace/ftrace/ftrace_stats.proto",
-        "perfetto/trace/ftrace/generic.proto",
-        "perfetto/trace/ftrace/i2c.proto",
-        "perfetto/trace/ftrace/ipi.proto",
-        "perfetto/trace/ftrace/irq.proto",
-        "perfetto/trace/ftrace/kmem.proto",
-        "perfetto/trace/ftrace/lowmemorykiller.proto",
-        "perfetto/trace/ftrace/mdss.proto",
-        "perfetto/trace/ftrace/mm_event.proto",
-        "perfetto/trace/ftrace/oom.proto",
-        "perfetto/trace/ftrace/power.proto",
-        "perfetto/trace/ftrace/raw_syscalls.proto",
-        "perfetto/trace/ftrace/regulator.proto",
-        "perfetto/trace/ftrace/sched.proto",
-        "perfetto/trace/ftrace/signal.proto",
-        "perfetto/trace/ftrace/sync.proto",
-        "perfetto/trace/ftrace/systrace.proto",
-        "perfetto/trace/ftrace/task.proto",
-        "perfetto/trace/ftrace/test_bundle_wrapper.proto",
-        "perfetto/trace/ftrace/vmscan.proto",
-        "perfetto/trace/ftrace/workqueue.proto",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/ftrace:zero_gen
-pbzero_cc_proto_library(
-    name = "trace_ftrace_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:trace_ftrace_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/gpu:lite_gen
-proto_library(
-    name = "trace_gpu",
-    srcs = [
-        "perfetto/trace/gpu/gpu_counter_event.proto",
-        "perfetto/trace/gpu/gpu_render_stage_event.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:common",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/gpu:lite_gen
-cc_proto_library(
-    name = "trace_gpu_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_gpu",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/gpu:lite_gen
-java_proto_library(
-    name = "trace_gpu_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_gpu",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/gpu:zero_gen
-proto_library(
-    name = "trace_gpu_zero",
-    srcs = [
-        "perfetto/trace/gpu/gpu_counter_event.proto",
-        "perfetto/trace/gpu/gpu_render_stage_event.proto",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:common_zero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/gpu:zero_gen
-pbzero_cc_proto_library(
-    name = "trace_gpu_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:trace_gpu_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/interned_data:lite_gen
-proto_library(
-    name = "trace_interned_data",
-    srcs = [
-        "perfetto/trace/interned_data/interned_data.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_profiling",
-        "//third_party/perfetto/protos:trace_track_event",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/interned_data:lite_gen
-cc_proto_library(
-    name = "trace_interned_data_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_interned_data",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/interned_data:lite_gen
-java_proto_library(
-    name = "trace_interned_data_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_interned_data",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/interned_data:zero_gen
-proto_library(
-    name = "trace_interned_data_zero",
-    srcs = [
-        "perfetto/trace/interned_data/interned_data.proto",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_profiling_zero",
-        "//third_party/perfetto/protos:trace_track_event_zero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/interned_data:zero_gen
-pbzero_cc_proto_library(
-    name = "trace_interned_data_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:trace_interned_data_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace:merged_trace_gen
-proto_library(
-    name = "trace_merged_trace_gen",
-    srcs = [
-        "perfetto/trace/perfetto_trace.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/perfetto/trace:merged_trace_gen
-cc_proto_library(
-    name = "trace_merged_trace_gen_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_merged_trace_gen",
-    ],
-)
-
-# GN target: //protos/perfetto/trace:merged_trace_gen
-java_proto_library(
-    name = "trace_merged_trace_gen_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_merged_trace_gen",
-    ],
-)
-
-# GN target: //protos/perfetto/trace:minimal_lite_gen
-proto_library(
-    name = "trace_minimal",
-    srcs = [
-        "perfetto/trace/clock_snapshot.proto",
-        "perfetto/trace/system_info.proto",
-        "perfetto/trace/trigger.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:common",
-        "//third_party/perfetto/protos:config",
-        "//third_party/perfetto/protos:config_android",
-        "//third_party/perfetto/protos:config_ftrace",
-        "//third_party/perfetto/protos:config_gpu",
-        "//third_party/perfetto/protos:config_inode_file",
-        "//third_party/perfetto/protos:config_power",
-        "//third_party/perfetto/protos:config_process_stats",
-        "//third_party/perfetto/protos:config_profiling",
-        "//third_party/perfetto/protos:config_sys_stats",
-    ],
-)
-
-# GN target: //protos/perfetto/trace:minimal_lite_gen
-cc_proto_library(
-    name = "trace_minimal_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_minimal",
-    ],
-)
-
-# GN target: //protos/perfetto/trace:minimal_lite_gen
-java_proto_library(
-    name = "trace_minimal_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_minimal",
-    ],
-)
-
-# GN target: //protos/perfetto/trace:minimal_zero_gen
-proto_library(
-    name = "trace_minimal_zero",
-    srcs = [
-        "perfetto/trace/clock_snapshot.proto",
-        "perfetto/trace/system_info.proto",
-        "perfetto/trace/trigger.proto",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:common_zero",
-        "//third_party/perfetto/protos:config_android_zero",
-        "//third_party/perfetto/protos:config_ftrace_zero",
-        "//third_party/perfetto/protos:config_gpu_zero",
-        "//third_party/perfetto/protos:config_inode_file_zero",
-        "//third_party/perfetto/protos:config_power_zero",
-        "//third_party/perfetto/protos:config_process_stats_zero",
-        "//third_party/perfetto/protos:config_profiling_zero",
-        "//third_party/perfetto/protos:config_sys_stats_zero",
-        "//third_party/perfetto/protos:config_zero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace:minimal_zero_gen
-pbzero_cc_proto_library(
-    name = "trace_minimal_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:trace_minimal_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace:non_minimal_lite_gen
-proto_library(
-    name = "trace_non_minimal",
-    srcs = [
-        "perfetto/trace/test_event.proto",
-        "perfetto/trace/trace.proto",
-        "perfetto/trace/trace_packet.proto",
-        "perfetto/trace/trace_packet_defaults.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:common",
-        "//third_party/perfetto/protos:config",
-        "//third_party/perfetto/protos:config_android",
-        "//third_party/perfetto/protos:config_ftrace",
-        "//third_party/perfetto/protos:config_gpu",
-        "//third_party/perfetto/protos:config_inode_file",
-        "//third_party/perfetto/protos:config_power",
-        "//third_party/perfetto/protos:config_process_stats",
-        "//third_party/perfetto/protos:config_profiling",
-        "//third_party/perfetto/protos:config_sys_stats",
-        "//third_party/perfetto/protos:trace_android",
-        "//third_party/perfetto/protos:trace_appended_data",
-        "//third_party/perfetto/protos:trace_chrome",
-        "//third_party/perfetto/protos:trace_filesystem",
-        "//third_party/perfetto/protos:trace_ftrace",
-        "//third_party/perfetto/protos:trace_gpu",
-        "//third_party/perfetto/protos:trace_interned_data",
-        "//third_party/perfetto/protos:trace_minimal",
-        "//third_party/perfetto/protos:trace_perfetto",
-        "//third_party/perfetto/protos:trace_power",
-        "//third_party/perfetto/protos:trace_profiling",
-        "//third_party/perfetto/protos:trace_ps",
-        "//third_party/perfetto/protos:trace_sys_stats",
-        "//third_party/perfetto/protos:trace_track_event",
-    ],
-)
-
-# GN target: //protos/perfetto/trace:non_minimal_lite_gen
-cc_proto_library(
-    name = "trace_non_minimal_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_non_minimal",
-    ],
-)
-
-# GN target: //protos/perfetto/trace:non_minimal_lite_gen
-java_proto_library(
-    name = "trace_non_minimal_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_non_minimal",
-    ],
-)
-
-# GN target: //protos/perfetto/trace:non_minimal_zero_gen
-proto_library(
-    name = "trace_non_minimal_zero",
-    srcs = [
-        "perfetto/trace/test_event.proto",
-        "perfetto/trace/trace.proto",
-        "perfetto/trace/trace_packet.proto",
-        "perfetto/trace/trace_packet_defaults.proto",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:common_zero",
-        "//third_party/perfetto/protos:config_android_zero",
-        "//third_party/perfetto/protos:config_ftrace_zero",
-        "//third_party/perfetto/protos:config_gpu_zero",
-        "//third_party/perfetto/protos:config_inode_file_zero",
-        "//third_party/perfetto/protos:config_power_zero",
-        "//third_party/perfetto/protos:config_process_stats_zero",
-        "//third_party/perfetto/protos:config_profiling_zero",
-        "//third_party/perfetto/protos:config_sys_stats_zero",
-        "//third_party/perfetto/protos:config_zero",
-        "//third_party/perfetto/protos:trace_android_zero",
-        "//third_party/perfetto/protos:trace_appended_data_zero",
-        "//third_party/perfetto/protos:trace_chrome_zero",
-        "//third_party/perfetto/protos:trace_filesystem_zero",
-        "//third_party/perfetto/protos:trace_ftrace_zero",
-        "//third_party/perfetto/protos:trace_gpu_zero",
-        "//third_party/perfetto/protos:trace_interned_data_zero",
-        "//third_party/perfetto/protos:trace_minimal_zero",
-        "//third_party/perfetto/protos:trace_perfetto_zero",
-        "//third_party/perfetto/protos:trace_power_zero",
-        "//third_party/perfetto/protos:trace_profiling_zero",
-        "//third_party/perfetto/protos:trace_ps_zero",
-        "//third_party/perfetto/protos:trace_sys_stats_zero",
-        "//third_party/perfetto/protos:trace_track_event_zero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace:non_minimal_zero_gen
-pbzero_cc_proto_library(
-    name = "trace_non_minimal_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:trace_non_minimal_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/perfetto:lite_gen
-proto_library(
-    name = "trace_perfetto",
-    srcs = [
-        "perfetto/trace/perfetto/perfetto_metatrace.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/perfetto:lite_gen
-cc_proto_library(
-    name = "trace_perfetto_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_perfetto",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/perfetto:lite_gen
-java_proto_library(
-    name = "trace_perfetto_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_perfetto",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/perfetto:zero_gen
-proto_library(
-    name = "trace_perfetto_zero",
-    srcs = [
-        "perfetto/trace/perfetto/perfetto_metatrace.proto",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/perfetto:zero_gen
-pbzero_cc_proto_library(
-    name = "trace_perfetto_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:trace_perfetto_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/power:lite_gen
-proto_library(
-    name = "trace_power",
-    srcs = [
-        "perfetto/trace/power/battery_counters.proto",
-        "perfetto/trace/power/power_rails.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/power:lite_gen
-cc_proto_library(
-    name = "trace_power_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_power",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/power:lite_gen
-java_proto_library(
-    name = "trace_power_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_power",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/power:zero_gen
-proto_library(
-    name = "trace_power_zero",
-    srcs = [
-        "perfetto/trace/power/battery_counters.proto",
-        "perfetto/trace/power/power_rails.proto",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/power:zero_gen
-pbzero_cc_proto_library(
-    name = "trace_power_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:trace_power_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace_processor:lite_gen
-proto_library(
-    name = "trace_processor",
-    srcs = [
-        "perfetto/trace_processor/raw_query.proto",
-        "perfetto/trace_processor/trace_processor.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/perfetto/trace_processor:lite_gen
-cc_proto_library(
-    name = "trace_processor_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_processor",
-    ],
-)
-
-# GN target: //protos/perfetto/trace_processor:lite_gen
-java_proto_library(
-    name = "trace_processor_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_processor",
-    ],
-)
-
-# GN target: //protos/perfetto/trace_processor:metrics_impl_zero_gen
-proto_library(
-    name = "trace_processor_metrics_impl_zero",
-    srcs = [
-        "perfetto/trace_processor/metrics_impl.proto",
-    ],
-)
-
-# GN target: //protos/perfetto/trace_processor:metrics_impl_zero_gen
-pbzero_cc_proto_library(
-    name = "trace_processor_metrics_impl_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:trace_processor_metrics_impl_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/profiling:lite_gen
-proto_library(
-    name = "trace_profiling",
-    srcs = [
-        "perfetto/trace/profiling/heap_graph.proto",
-        "perfetto/trace/profiling/profile_common.proto",
-        "perfetto/trace/profiling/profile_packet.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/profiling:lite_gen
-cc_proto_library(
-    name = "trace_profiling_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_profiling",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/profiling:lite_gen
-java_proto_library(
-    name = "trace_profiling_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_profiling",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/profiling:zero_gen
-proto_library(
-    name = "trace_profiling_zero",
-    srcs = [
-        "perfetto/trace/profiling/heap_graph.proto",
-        "perfetto/trace/profiling/profile_common.proto",
-        "perfetto/trace/profiling/profile_packet.proto",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/profiling:zero_gen
-pbzero_cc_proto_library(
-    name = "trace_profiling_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:trace_profiling_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/ps:lite_gen
-proto_library(
-    name = "trace_ps",
-    srcs = [
-        "perfetto/trace/ps/process_stats.proto",
-        "perfetto/trace/ps/process_tree.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/ps:lite_gen
-cc_proto_library(
-    name = "trace_ps_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_ps",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/ps:lite_gen
-java_proto_library(
-    name = "trace_ps_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_ps",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/ps:zero_gen
-proto_library(
-    name = "trace_ps_zero",
-    srcs = [
-        "perfetto/trace/ps/process_stats.proto",
-        "perfetto/trace/ps/process_tree.proto",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/ps:zero_gen
-pbzero_cc_proto_library(
-    name = "trace_ps_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:trace_ps_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/sys_stats:lite_gen
-proto_library(
-    name = "trace_sys_stats",
-    srcs = [
-        "perfetto/trace/sys_stats/sys_stats.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:common",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/sys_stats:lite_gen
-cc_proto_library(
-    name = "trace_sys_stats_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_sys_stats",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/sys_stats:lite_gen
-java_proto_library(
-    name = "trace_sys_stats_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_sys_stats",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/sys_stats:zero_gen
-proto_library(
-    name = "trace_sys_stats_zero",
-    srcs = [
-        "perfetto/trace/sys_stats/sys_stats.proto",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:common_zero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/sys_stats:zero_gen
-pbzero_cc_proto_library(
-    name = "trace_sys_stats_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:trace_sys_stats_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/track_event:lite_gen
-proto_library(
-    name = "trace_track_event",
-    srcs = [
-        "perfetto/trace/track_event/debug_annotation.proto",
-        "perfetto/trace/track_event/log_message.proto",
-        "perfetto/trace/track_event/process_descriptor.proto",
-        "perfetto/trace/track_event/source_location.proto",
-        "perfetto/trace/track_event/task_execution.proto",
-        "perfetto/trace/track_event/thread_descriptor.proto",
-        "perfetto/trace/track_event/track_descriptor.proto",
-        "perfetto/trace/track_event/track_event.proto",
-    ],
-    has_services = 1,
-    cc_api_version = 2,
-    cc_generic_services = 1,
-    visibility = [
-        "//visibility:public",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/track_event:lite_gen
-cc_proto_library(
-    name = "trace_track_event_cc_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_track_event",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/track_event:lite_gen
-java_proto_library(
-    name = "trace_track_event_java_proto",
-    visibility = [
-        "//visibility:public",
-    ],
-    deps = [
-        "//third_party/perfetto/protos:trace_track_event",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/track_event:zero_gen
-proto_library(
-    name = "trace_track_event_zero",
-    srcs = [
-        "perfetto/trace/track_event/debug_annotation.proto",
-        "perfetto/trace/track_event/log_message.proto",
-        "perfetto/trace/track_event/process_descriptor.proto",
-        "perfetto/trace/track_event/source_location.proto",
-        "perfetto/trace/track_event/task_execution.proto",
-        "perfetto/trace/track_event/thread_descriptor.proto",
-        "perfetto/trace/track_event/track_descriptor.proto",
-        "perfetto/trace/track_event/track_event.proto",
-    ],
-)
-
-# GN target: //protos/perfetto/trace/track_event:zero_gen
-pbzero_cc_proto_library(
-    name = "trace_track_event_zero_cc_proto",
-    src_proto_library = "//third_party/perfetto/protos:trace_track_event_zero",
-    deps = [
-        "//third_party/perfetto:libprotozero",
-    ],
-)
diff --git a/protos/perfetto/config/ftrace/ftrace_config.proto b/protos/perfetto/config/ftrace/ftrace_config.proto
index 5eed9ae..24e5bce 100644
--- a/protos/perfetto/config/ftrace/ftrace_config.proto
+++ b/protos/perfetto/config/ftrace/ftrace_config.proto
@@ -29,4 +29,18 @@
   // *Per-CPU* buffer size.
   optional uint32 buffer_size_kb = 10;
   optional uint32 drain_period_ms = 11;
+
+  // Configuration for compact encoding of scheduler events. If enabled, this
+  // records a small subset of fields of selected scheduling events, and
+  // encodes them in a denser proto format than normal. This is useful due to
+  // scheduling events being abundant in a typical trace, and dominating its
+  // size via a combination of unnecessary data being retained, and proto
+  // format overheads.
+  // TODO(rsavitski): unstable, do not use.
+  message CompactSchedConfig {
+    // If true, and sched_switch ftrace event is enabled, record those events
+    // in the compact format.
+    optional bool enabled = 1;
+  }
+  optional CompactSchedConfig compact_sched = 12;
 }
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index 259a8b0..3a4ba7f 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -635,6 +635,20 @@
   // *Per-CPU* buffer size.
   optional uint32 buffer_size_kb = 10;
   optional uint32 drain_period_ms = 11;
+
+  // Configuration for compact encoding of scheduler events. If enabled, this
+  // records a small subset of fields of selected scheduling events, and
+  // encodes them in a denser proto format than normal. This is useful due to
+  // scheduling events being abundant in a typical trace, and dominating its
+  // size via a combination of unnecessary data being retained, and proto
+  // format overheads.
+  // TODO(rsavitski): unstable, do not use.
+  message CompactSchedConfig {
+    // If true, and sched_switch ftrace event is enabled, record those events
+    // in the compact format.
+    optional bool enabled = 1;
+  }
+  optional CompactSchedConfig compact_sched = 12;
 }
 
 // End of protos/perfetto/config/ftrace/ftrace_config.proto
diff --git a/protos/perfetto/ipc/producer_port.proto b/protos/perfetto/ipc/producer_port.proto
index 99241ac..eab011a 100644
--- a/protos/perfetto/ipc/producer_port.proto
+++ b/protos/perfetto/ipc/producer_port.proto
@@ -69,7 +69,7 @@
       returns (NotifyDataSourceStartedResponse) {}
 
   // Sent by the client in response to a StopDataSource message, when a data
-  // source is succesfully stopped. This is expected only for data sources that
+  // source is successfully stopped. This is expected only for data sources that
   // set the DataSourceDescriptor.will_notify_on_stop flag when registering.
   rpc NotifyDataSourceStopped(NotifyDataSourceStoppedRequest)
       returns (NotifyDataSourceStoppedResponse) {}
diff --git a/protos/perfetto/trace/ftrace/ftrace_event_bundle.proto b/protos/perfetto/trace/ftrace/ftrace_event_bundle.proto
index 08f0cf7..7cd0594 100644
--- a/protos/perfetto/trace/ftrace/ftrace_event_bundle.proto
+++ b/protos/perfetto/trace/ftrace/ftrace_event_bundle.proto
@@ -21,10 +21,36 @@
 
 package perfetto.protos;
 
-// One parsed page from per-cpu ftrace buffer.
+// The result of tracing one or more ftrace data pages from a single per-cpu
+// kernel ring buffer. If collating multiple pages' worth of events, all of
+// them come from contiguous pages, with no kernel data loss in between.
 message FtraceEventBundle {
   optional uint32 cpu = 1;
   repeated FtraceEvent event = 2;
-  // True if this cpu's ftrace kernel buffer lost events since the last read.
+  // Set to true if there was data loss between the last time we've read from
+  // the corresponding per-cpu kernel buffer, and the earliest event recorded
+  // in this bundle.
   optional bool lost_events = 3;
+
+  // Optionally-enabled compact encoding of a batch of scheduling events. Only
+  // a subset of events & their fields is recorded.
+  // All fields (except comms) are stored in a structure-of-arrays form, one
+  // entry in each repeated field per event.
+  // TODO(rsavitski): unstable, do not use.
+  message CompactSched {
+    // Delta-encoded timestamps across all sched_switch events within this
+    // bundle. The first is absolute, each next one is relative to its
+    // predecessor.
+    repeated uint64 switch_timestamp = 1 [packed = true];
+    repeated int32 switch_prev_state = 2 [packed = true];
+    repeated int32 switch_next_pid = 3 [packed = true];
+    repeated int32 switch_next_prio = 4 [packed = true];
+
+    // Interned table of unique comm strings for this bundle.
+    repeated string switch_next_comm_table = 5;
+    // One per event, index into |switch_next_comm_table| corresponding to the
+    // next_comm field of the event.
+    repeated uint32 switch_next_comm_index = 6 [packed = true];
+  }
+  optional CompactSched compact_sched = 4;
 }
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index 1c24dd5..88b4fa3 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -2312,12 +2312,38 @@
 
 // Begin of protos/perfetto/trace/ftrace/ftrace_event_bundle.proto
 
-// One parsed page from per-cpu ftrace buffer.
+// The result of tracing one or more ftrace data pages from a single per-cpu
+// kernel ring buffer. If collating multiple pages' worth of events, all of
+// them come from contiguous pages, with no kernel data loss in between.
 message FtraceEventBundle {
   optional uint32 cpu = 1;
   repeated FtraceEvent event = 2;
-  // True if this cpu's ftrace kernel buffer lost events since the last read.
+  // Set to true if there was data loss between the last time we've read from
+  // the corresponding per-cpu kernel buffer, and the earliest event recorded
+  // in this bundle.
   optional bool lost_events = 3;
+
+  // Optionally-enabled compact encoding of a batch of scheduling events. Only
+  // a subset of events & their fields is recorded.
+  // All fields (except comms) are stored in a structure-of-arrays form, one
+  // entry in each repeated field per event.
+  // TODO(rsavitski): unstable, do not use.
+  message CompactSched {
+    // Delta-encoded timestamps across all sched_switch events within this
+    // bundle. The first is absolute, each next one is relative to its
+    // predecessor.
+    repeated uint64 switch_timestamp = 1 [packed = true];
+    repeated int32 switch_prev_state = 2 [packed = true];
+    repeated int32 switch_next_pid = 3 [packed = true];
+    repeated int32 switch_next_prio = 4 [packed = true];
+
+    // Interned table of unique comm strings for this bundle.
+    repeated string switch_next_comm_table = 5;
+    // One per event, index into |switch_next_comm_table| corresponding to the
+    // next_comm field of the event.
+    repeated uint32 switch_next_comm_index = 6 [packed = true];
+  }
+  optional CompactSched compact_sched = 4;
 }
 
 // End of protos/perfetto/trace/ftrace/ftrace_event_bundle.proto
@@ -4260,6 +4286,20 @@
   // *Per-CPU* buffer size.
   optional uint32 buffer_size_kb = 10;
   optional uint32 drain_period_ms = 11;
+
+  // Configuration for compact encoding of scheduler events. If enabled, this
+  // records a small subset of fields of selected scheduling events, and
+  // encodes them in a denser proto format than normal. This is useful due to
+  // scheduling events being abundant in a typical trace, and dominating its
+  // size via a combination of unnecessary data being retained, and proto
+  // format overheads.
+  // TODO(rsavitski): unstable, do not use.
+  message CompactSchedConfig {
+    // If true, and sched_switch ftrace event is enabled, record those events
+    // in the compact format.
+    optional bool enabled = 1;
+  }
+  optional CompactSchedConfig compact_sched = 12;
 }
 
 // End of protos/perfetto/config/ftrace/ftrace_config.proto
diff --git a/src/base/unix_socket.cc b/src/base/unix_socket.cc
index c93b3ca..663cb14 100644
--- a/src/base/unix_socket.cc
+++ b/src/base/unix_socket.cc
@@ -611,7 +611,7 @@
     return true;
   }
 
-  // If sendmsg() succeds but the returned size is < |len| it means that the
+  // If sendmsg() succeeds but the returned size is < |len| it means that the
   // endpoint disconnected in the middle of the read, and we managed to send
   // only a portion of the buffer. In this case we should just give up.
 
diff --git a/src/ipc/BUILD.gn b/src/ipc/BUILD.gn
index 12353de..ed0ecd2 100644
--- a/src/ipc/BUILD.gn
+++ b/src/ipc/BUILD.gn
@@ -30,6 +30,7 @@
   ]
   deps = [
     "../../gn:default_deps",
+    "../../gn:protobuf_lite",
     "../../protos/perfetto/ipc:wire_protocol",
     "../base",
   ]
@@ -86,3 +87,12 @@
   proto_in_dir = perfetto_root_path
   proto_out_dir = perfetto_root_path
 }
+
+# This is used by Bazel BUILD rules.
+static_library("perfetto_ipc") {
+  complete_static_lib = true
+  deps = [
+    ":ipc",
+    "../../gn:default_deps",
+  ]
+}
diff --git a/src/perfetto_cmd/perfetto_config.descriptor.h b/src/perfetto_cmd/perfetto_config.descriptor.h
index 0a47df1..8fae890 100644
--- a/src/perfetto_cmd/perfetto_config.descriptor.h
+++ b/src/perfetto_cmd/perfetto_config.descriptor.h
@@ -12,15 +12,15 @@
 // SHA1(tools/gen_binary_descriptors)
 // 8958deee3293aa8e5cc4fd677a868f14f1178f73
 // SHA1(protos/perfetto/config/perfetto_config.proto)
-// 203069192a7193cc87f04c4927ec78dc4797366c
+// 941c23e0c118e3f956746fe0b4cc82e221d4e4c7
 
 // This is the proto PerfettoConfig encoded as a ProtoFileDescriptor to allow
 // for reflection without libprotobuf full/non-lite protos.
 
 namespace perfetto {
 
-constexpr std::array<uint8_t, 16587> kPerfettoConfigDescriptor{
-    {0x0a, 0xc7, 0x81, 0x01, 0x0a, 0x2c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+constexpr std::array<uint8_t, 16722> kPerfettoConfigDescriptor{
+    {0x0a, 0xce, 0x82, 0x01, 0x0a, 0x2c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
      0x2f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2f, 0x63, 0x6f,
      0x6e, 0x66, 0x69, 0x67, 0x2f, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
      0x6f, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f,
@@ -470,8 +470,8 @@
      0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54,
      0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x66,
      0x6f, 0x72, 0x54, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4a, 0x0b, 0x08,
-     0xff, 0xff, 0xff, 0x7f, 0x10, 0x80, 0x80, 0x80, 0x80, 0x01, 0x22, 0xcf,
-     0x01, 0x0a, 0x0c, 0x46, 0x74, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e,
+     0xff, 0xff, 0xff, 0x7f, 0x10, 0x80, 0x80, 0x80, 0x80, 0x01, 0x22, 0xd6,
+     0x02, 0x0a, 0x0c, 0x46, 0x74, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e,
      0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x74, 0x72, 0x61, 0x63,
      0x65, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03,
      0x28, 0x09, 0x52, 0x0c, 0x66, 0x74, 0x72, 0x61, 0x63, 0x65, 0x45, 0x76,
@@ -488,921 +488,932 @@
      0x12, 0x26, 0x0a, 0x0f, 0x64, 0x72, 0x61, 0x69, 0x6e, 0x5f, 0x70, 0x65,
      0x72, 0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28,
      0x0d, 0x52, 0x0d, 0x64, 0x72, 0x61, 0x69, 0x6e, 0x50, 0x65, 0x72, 0x69,
-     0x6f, 0x64, 0x4d, 0x73, 0x22, 0x95, 0x03, 0x0a, 0x0f, 0x49, 0x6e, 0x6f,
-     0x64, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-     0x12, 0x28, 0x0a, 0x10, 0x73, 0x63, 0x61, 0x6e, 0x5f, 0x69, 0x6e, 0x74,
-     0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01,
-     0x28, 0x0d, 0x52, 0x0e, 0x73, 0x63, 0x61, 0x6e, 0x49, 0x6e, 0x74, 0x65,
-     0x72, 0x76, 0x61, 0x6c, 0x4d, 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x73, 0x63,
-     0x61, 0x6e, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x6d, 0x73, 0x18,
-     0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x73, 0x63, 0x61, 0x6e, 0x44,
-     0x65, 0x6c, 0x61, 0x79, 0x4d, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x63,
-     0x61, 0x6e, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x69, 0x7a,
-     0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x73, 0x63, 0x61,
-     0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1e,
-     0x0a, 0x0b, 0x64, 0x6f, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x73, 0x63, 0x61,
-     0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x64, 0x6f, 0x4e,
-     0x6f, 0x74, 0x53, 0x63, 0x61, 0x6e, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x63,
-     0x61, 0x6e, 0x5f, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x6f, 0x69,
-     0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x73,
-     0x63, 0x61, 0x6e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e,
-     0x74, 0x73, 0x12, 0x67, 0x0a, 0x13, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f,
-     0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e,
-     0x67, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x70, 0x65,
-     0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-     0x73, 0x2e, 0x49, 0x6e, 0x6f, 0x64, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x43,
-     0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x50,
+     0x6f, 0x64, 0x4d, 0x73, 0x12, 0x55, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70,
+     0x61, 0x63, 0x74, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x18, 0x0c, 0x20,
+     0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
+     0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x46, 0x74,
+     0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43,
+     0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x43,
+     0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0c, 0x63, 0x6f, 0x6d, 0x70, 0x61,
+     0x63, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x1a, 0x2e, 0x0a, 0x12, 0x43,
+     0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x53, 0x63, 0x68, 0x65, 0x64, 0x43,
+     0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61,
+     0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07,
+     0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0x95, 0x03, 0x0a, 0x0f,
+     0x49, 0x6e, 0x6f, 0x64, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6e,
+     0x66, 0x69, 0x67, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x63, 0x61, 0x6e, 0x5f,
+     0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x6d, 0x73, 0x18,
+     0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x73, 0x63, 0x61, 0x6e, 0x49,
+     0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x73, 0x12, 0x22, 0x0a,
+     0x0d, 0x73, 0x63, 0x61, 0x6e, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f,
+     0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x73, 0x63,
+     0x61, 0x6e, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x73, 0x12, 0x26, 0x0a,
+     0x0f, 0x73, 0x63, 0x61, 0x6e, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f,
+     0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d,
+     0x73, 0x63, 0x61, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x53, 0x69, 0x7a,
+     0x65, 0x12, 0x1e, 0x0a, 0x0b, 0x64, 0x6f, 0x5f, 0x6e, 0x6f, 0x74, 0x5f,
+     0x73, 0x63, 0x61, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09,
+     0x64, 0x6f, 0x4e, 0x6f, 0x74, 0x53, 0x63, 0x61, 0x6e, 0x12, 0x2a, 0x0a,
+     0x11, 0x73, 0x63, 0x61, 0x6e, 0x5f, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f,
+     0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09,
+     0x52, 0x0f, 0x73, 0x63, 0x61, 0x6e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x50,
+     0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x67, 0x0a, 0x13, 0x6d, 0x6f, 0x75,
+     0x6e, 0x74, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x70,
+     0x70, 0x69, 0x6e, 0x67, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37,
+     0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
+     0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x6f, 0x64, 0x65, 0x46, 0x69,
+     0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4d, 0x6f, 0x75,
+     0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69,
+     0x6e, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x6d, 0x6f, 0x75,
+     0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69,
+     0x6e, 0x67, 0x1a, 0x57, 0x0a, 0x16, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x50,
      0x6f, 0x69, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x45,
-     0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50,
-     0x6f, 0x69, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x1a,
-     0x57, 0x0a, 0x16, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e,
-     0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x45, 0x6e, 0x74, 0x72,
-     0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x70, 0x6f,
-     0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d,
-     0x6f, 0x75, 0x6e, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1d, 0x0a,
-     0x0a, 0x73, 0x63, 0x61, 0x6e, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x18,
-     0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x73, 0x63, 0x61, 0x6e, 0x52,
-     0x6f, 0x6f, 0x74, 0x73, 0x22, 0x81, 0x03, 0x0a, 0x12, 0x41, 0x6e, 0x64,
-     0x72, 0x6f, 0x69, 0x64, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x43, 0x6f, 0x6e,
-     0x66, 0x69, 0x67, 0x12, 0x26, 0x0a, 0x0f, 0x62, 0x61, 0x74, 0x74, 0x65,
-     0x72, 0x79, 0x5f, 0x70, 0x6f, 0x6c, 0x6c, 0x5f, 0x6d, 0x73, 0x18, 0x01,
-     0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72,
-     0x79, 0x50, 0x6f, 0x6c, 0x6c, 0x4d, 0x73, 0x12, 0x5e, 0x0a, 0x10, 0x62,
-     0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74,
-     0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x33, 0x2e,
-     0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
-     0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50,
-     0x6f, 0x77, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x42,
-     0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65,
-     0x72, 0x73, 0x52, 0x0f, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x43,
-     0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x63,
-     0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72,
-     0x5f, 0x72, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
-     0x52, 0x11, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x50, 0x6f, 0x77,
-     0x65, 0x72, 0x52, 0x61, 0x69, 0x6c, 0x73, 0x22, 0xb2, 0x01, 0x0a, 0x0f,
-     0x42, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x75, 0x6e, 0x74,
-     0x65, 0x72, 0x73, 0x12, 0x1f, 0x0a, 0x1b, 0x42, 0x41, 0x54, 0x54, 0x45,
-     0x52, 0x59, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x55,
-     0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00,
-     0x12, 0x1a, 0x0a, 0x16, 0x42, 0x41, 0x54, 0x54, 0x45, 0x52, 0x59, 0x5f,
-     0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x43, 0x48, 0x41, 0x52,
-     0x47, 0x45, 0x10, 0x01, 0x12, 0x24, 0x0a, 0x20, 0x42, 0x41, 0x54, 0x54,
-     0x45, 0x52, 0x59, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f,
-     0x43, 0x41, 0x50, 0x41, 0x43, 0x49, 0x54, 0x59, 0x5f, 0x50, 0x45, 0x52,
-     0x43, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x42, 0x41,
+     0x6e, 0x74, 0x72, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x6f, 0x75, 0x6e,
+     0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+     0x52, 0x0a, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74,
+     0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x63, 0x61, 0x6e, 0x5f, 0x72, 0x6f, 0x6f,
+     0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x73, 0x63,
+     0x61, 0x6e, 0x52, 0x6f, 0x6f, 0x74, 0x73, 0x22, 0x81, 0x03, 0x0a, 0x12,
+     0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x50, 0x6f, 0x77, 0x65, 0x72,
+     0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x26, 0x0a, 0x0f, 0x62, 0x61,
+     0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x70, 0x6f, 0x6c, 0x6c, 0x5f, 0x6d,
+     0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x62, 0x61, 0x74,
+     0x74, 0x65, 0x72, 0x79, 0x50, 0x6f, 0x6c, 0x6c, 0x4d, 0x73, 0x12, 0x5e,
+     0x0a, 0x10, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x63, 0x6f,
+     0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e,
+     0x32, 0x33, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
+     0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x41, 0x6e, 0x64, 0x72, 0x6f,
+     0x69, 0x64, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+     0x67, 0x2e, 0x42, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x75,
+     0x6e, 0x74, 0x65, 0x72, 0x73, 0x52, 0x0f, 0x62, 0x61, 0x74, 0x74, 0x65,
+     0x72, 0x79, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2e,
+     0x0a, 0x13, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x5f, 0x70, 0x6f,
+     0x77, 0x65, 0x72, 0x5f, 0x72, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20,
+     0x01, 0x28, 0x08, 0x52, 0x11, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74,
+     0x50, 0x6f, 0x77, 0x65, 0x72, 0x52, 0x61, 0x69, 0x6c, 0x73, 0x22, 0xb2,
+     0x01, 0x0a, 0x0f, 0x42, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x43, 0x6f,
+     0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1f, 0x0a, 0x1b, 0x42, 0x41,
      0x54, 0x54, 0x45, 0x52, 0x59, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45,
-     0x52, 0x5f, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x54, 0x10, 0x03, 0x12,
-     0x1f, 0x0a, 0x1b, 0x42, 0x41, 0x54, 0x54, 0x45, 0x52, 0x59, 0x5f, 0x43,
-     0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x43, 0x55, 0x52, 0x52, 0x45,
-     0x4e, 0x54, 0x5f, 0x41, 0x56, 0x47, 0x10, 0x04, 0x22, 0x80, 0x03, 0x0a,
-     0x12, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74,
-     0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42, 0x0a, 0x06, 0x71,
-     0x75, 0x69, 0x72, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32,
-     0x2a, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70,
-     0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73,
-     0x73, 0x53, 0x74, 0x61, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-     0x2e, 0x51, 0x75, 0x69, 0x72, 0x6b, 0x73, 0x52, 0x06, 0x71, 0x75, 0x69,
-     0x72, 0x6b, 0x73, 0x12, 0x3c, 0x0a, 0x1b, 0x73, 0x63, 0x61, 0x6e, 0x5f,
-     0x61, 0x6c, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65,
-     0x73, 0x5f, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02,
-     0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x73, 0x63, 0x61, 0x6e, 0x41, 0x6c,
-     0x6c, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x4f, 0x6e,
-     0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x72, 0x65, 0x63,
-     0x6f, 0x72, 0x64, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6e,
-     0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11,
-     0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64,
-     0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x12, 0x70, 0x72, 0x6f,
-     0x63, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x6c,
-     0x5f, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x70,
-     0x72, 0x6f, 0x63, 0x53, 0x74, 0x61, 0x74, 0x73, 0x50, 0x6f, 0x6c, 0x6c,
-     0x4d, 0x73, 0x12, 0x34, 0x0a, 0x17, 0x70, 0x72, 0x6f, 0x63, 0x5f, 0x73,
-     0x74, 0x61, 0x74, 0x73, 0x5f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x74,
-     0x74, 0x6c, 0x5f, 0x6d, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52,
-     0x13, 0x70, 0x72, 0x6f, 0x63, 0x53, 0x74, 0x61, 0x74, 0x73, 0x43, 0x61,
-     0x63, 0x68, 0x65, 0x54, 0x74, 0x6c, 0x4d, 0x73, 0x22, 0x55, 0x0a, 0x06,
-     0x51, 0x75, 0x69, 0x72, 0x6b, 0x73, 0x12, 0x16, 0x0a, 0x12, 0x51, 0x55,
-     0x49, 0x52, 0x4b, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49,
-     0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x14, 0x44, 0x49,
-     0x53, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41,
-     0x4c, 0x5f, 0x44, 0x55, 0x4d, 0x50, 0x10, 0x01, 0x1a, 0x02, 0x08, 0x01,
-     0x12, 0x15, 0x0a, 0x11, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x5f,
-     0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4d, 0x41, 0x4e, 0x44, 0x10, 0x02, 0x22,
-     0xf3, 0x03, 0x0a, 0x0e, 0x53, 0x79, 0x73, 0x53, 0x74, 0x61, 0x74, 0x73,
-     0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2a, 0x0a, 0x11, 0x6d, 0x65,
-     0x6d, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64,
-     0x5f, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x6d,
-     0x65, 0x6d, 0x69, 0x6e, 0x66, 0x6f, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64,
-     0x4d, 0x73, 0x12, 0x4b, 0x0a, 0x10, 0x6d, 0x65, 0x6d, 0x69, 0x6e, 0x66,
-     0x6f, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02,
-     0x20, 0x03, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
-     0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4d,
-     0x65, 0x6d, 0x69, 0x6e, 0x66, 0x6f, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65,
-     0x72, 0x73, 0x52, 0x0f, 0x6d, 0x65, 0x6d, 0x69, 0x6e, 0x66, 0x6f, 0x43,
-     0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x76,
-     0x6d, 0x73, 0x74, 0x61, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64,
-     0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x76,
-     0x6d, 0x73, 0x74, 0x61, 0x74, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x4d,
-     0x73, 0x12, 0x48, 0x0a, 0x0f, 0x76, 0x6d, 0x73, 0x74, 0x61, 0x74, 0x5f,
-     0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03,
-     0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
-     0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x56, 0x6d, 0x73,
-     0x74, 0x61, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x52,
-     0x0e, 0x76, 0x6d, 0x73, 0x74, 0x61, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74,
-     0x65, 0x72, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x5f,
-     0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73, 0x18, 0x05, 0x20,
-     0x01, 0x28, 0x0d, 0x52, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x50, 0x65, 0x72,
-     0x69, 0x6f, 0x64, 0x4d, 0x73, 0x12, 0x51, 0x0a, 0x0d, 0x73, 0x74, 0x61,
-     0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x18, 0x06,
-     0x20, 0x03, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
-     0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x53,
-     0x79, 0x73, 0x53, 0x74, 0x61, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69,
-     0x67, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65,
-     0x72, 0x73, 0x52, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x43, 0x6f, 0x75, 0x6e,
-     0x74, 0x65, 0x72, 0x73, 0x22, 0x7b, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x74,
-     0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x14, 0x0a, 0x10,
-     0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49,
-     0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54,
-     0x41, 0x54, 0x5f, 0x43, 0x50, 0x55, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x53,
-     0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x49,
-     0x52, 0x51, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x53, 0x10, 0x02, 0x12,
-     0x17, 0x0a, 0x13, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x53, 0x4f, 0x46, 0x54,
-     0x49, 0x52, 0x51, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x53, 0x10, 0x03,
-     0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x46, 0x4f, 0x52,
-     0x4b, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x04, 0x22, 0x9e, 0x06,
-     0x0a, 0x0a, 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-     0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f,
-     0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52,
-     0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x75, 0x6e,
-     0x74, 0x12, 0x35, 0x0a, 0x17, 0x6d, 0x61, 0x78, 0x5f, 0x6d, 0x65, 0x73,
-     0x73, 0x61, 0x67, 0x65, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x65,
-     0x63, 0x6f, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x14,
-     0x6d, 0x61, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x50,
-     0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04,
-     0x73, 0x65, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04,
-     0x73, 0x65, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x65, 0x73, 0x73,
-     0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01,
-     0x28, 0x0d, 0x52, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53,
-     0x69, 0x7a, 0x65, 0x12, 0x33, 0x0a, 0x16, 0x73, 0x65, 0x6e, 0x64, 0x5f,
-     0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x67,
-     0x69, 0x73, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52,
-     0x13, 0x73, 0x65, 0x6e, 0x64, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4f, 0x6e,
-     0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x4a, 0x0a, 0x0c,
-     0x64, 0x75, 0x6d, 0x6d, 0x79, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73,
-     0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x65, 0x72,
-     0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
-     0x2e, 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e,
-     0x44, 0x75, 0x6d, 0x6d, 0x79, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x52,
-     0x0b, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73,
-     0x1a, 0xfb, 0x03, 0x0a, 0x0b, 0x44, 0x75, 0x6d, 0x6d, 0x79, 0x46, 0x69,
-     0x65, 0x6c, 0x64, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x69, 0x65, 0x6c,
-     0x64, 0x5f, 0x75, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, 0x01, 0x20, 0x01,
-     0x28, 0x0d, 0x52, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x55, 0x69, 0x6e,
-     0x74, 0x33, 0x32, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64,
-     0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
-     0x52, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x49, 0x6e, 0x74, 0x33, 0x32,
-     0x12, 0x21, 0x0a, 0x0c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x75, 0x69,
-     0x6e, 0x74, 0x36, 0x34, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b,
-     0x66, 0x69, 0x65, 0x6c, 0x64, 0x55, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x12,
-     0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x69, 0x6e, 0x74,
-     0x36, 0x34, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x66, 0x69,
-     0x65, 0x6c, 0x64, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x23, 0x0a, 0x0d,
-     0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x66, 0x69, 0x78, 0x65, 0x64, 0x36,
-     0x34, 0x18, 0x05, 0x20, 0x01, 0x28, 0x06, 0x52, 0x0c, 0x66, 0x69, 0x65,
-     0x6c, 0x64, 0x46, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x12, 0x25, 0x0a,
-     0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x73, 0x66, 0x69, 0x78, 0x65,
-     0x64, 0x36, 0x34, 0x18, 0x06, 0x20, 0x01, 0x28, 0x10, 0x52, 0x0d, 0x66,
-     0x69, 0x65, 0x6c, 0x64, 0x53, 0x66, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34,
-     0x12, 0x23, 0x0a, 0x0d, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x66, 0x69,
-     0x78, 0x65, 0x64, 0x33, 0x32, 0x18, 0x07, 0x20, 0x01, 0x28, 0x07, 0x52,
-     0x0c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x46, 0x69, 0x78, 0x65, 0x64, 0x33,
-     0x32, 0x12, 0x25, 0x0a, 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x73,
-     0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x18, 0x08, 0x20, 0x01, 0x28,
-     0x0f, 0x52, 0x0d, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x66, 0x69, 0x78,
-     0x65, 0x64, 0x33, 0x32, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x69, 0x65, 0x6c,
-     0x64, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01,
-     0x28, 0x01, 0x52, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x6f, 0x75,
-     0x62, 0x6c, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64,
-     0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x02,
-     0x52, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x46, 0x6c, 0x6f, 0x61, 0x74,
-     0x12, 0x21, 0x0a, 0x0c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x73, 0x69,
-     0x6e, 0x74, 0x36, 0x34, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x12, 0x52, 0x0b,
-     0x66, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x12,
-     0x21, 0x0a, 0x0c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x73, 0x69, 0x6e,
-     0x74, 0x33, 0x32, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x11, 0x52, 0x0b, 0x66,
-     0x69, 0x65, 0x6c, 0x64, 0x53, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x12, 0x21,
-     0x0a, 0x0c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x73, 0x74, 0x72, 0x69,
-     0x6e, 0x67, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x69,
-     0x65, 0x6c, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x1f, 0x0a,
-     0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73,
-     0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x66, 0x69, 0x65, 0x6c,
-     0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0xd1, 0x1a, 0x0a, 0x0b, 0x54,
-     0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x43,
-     0x0a, 0x07, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20,
-     0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
-     0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72,
-     0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x42, 0x75,
-     0x66, 0x66, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x07,
-     0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x73, 0x12, 0x4a, 0x0a, 0x0c, 0x64,
-     0x61, 0x74, 0x61, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18,
-     0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x65, 0x72, 0x66,
+     0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45,
+     0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x42, 0x41, 0x54, 0x54, 0x45,
+     0x52, 0x59, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x43,
+     0x48, 0x41, 0x52, 0x47, 0x45, 0x10, 0x01, 0x12, 0x24, 0x0a, 0x20, 0x42,
+     0x41, 0x54, 0x54, 0x45, 0x52, 0x59, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54,
+     0x45, 0x52, 0x5f, 0x43, 0x41, 0x50, 0x41, 0x43, 0x49, 0x54, 0x59, 0x5f,
+     0x50, 0x45, 0x52, 0x43, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x1b, 0x0a,
+     0x17, 0x42, 0x41, 0x54, 0x54, 0x45, 0x52, 0x59, 0x5f, 0x43, 0x4f, 0x55,
+     0x4e, 0x54, 0x45, 0x52, 0x5f, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x54,
+     0x10, 0x03, 0x12, 0x1f, 0x0a, 0x1b, 0x42, 0x41, 0x54, 0x54, 0x45, 0x52,
+     0x59, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x43, 0x55,
+     0x52, 0x52, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x56, 0x47, 0x10, 0x04, 0x22,
+     0x80, 0x03, 0x0a, 0x12, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x53,
+     0x74, 0x61, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42,
+     0x0a, 0x06, 0x71, 0x75, 0x69, 0x72, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03,
+     0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
+     0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x50, 0x72, 0x6f,
+     0x63, 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74, 0x73, 0x43, 0x6f, 0x6e,
+     0x66, 0x69, 0x67, 0x2e, 0x51, 0x75, 0x69, 0x72, 0x6b, 0x73, 0x52, 0x06,
+     0x71, 0x75, 0x69, 0x72, 0x6b, 0x73, 0x12, 0x3c, 0x0a, 0x1b, 0x73, 0x63,
+     0x61, 0x6e, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65,
+     0x73, 0x73, 0x65, 0x73, 0x5f, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x72,
+     0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x73, 0x63, 0x61,
+     0x6e, 0x41, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65,
+     0x73, 0x4f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2e, 0x0a, 0x13,
+     0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x61,
+     0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28,
+     0x08, 0x52, 0x11, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x68, 0x72,
+     0x65, 0x61, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x12,
+     0x70, 0x72, 0x6f, 0x63, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x70,
+     0x6f, 0x6c, 0x6c, 0x5f, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d,
+     0x52, 0x0f, 0x70, 0x72, 0x6f, 0x63, 0x53, 0x74, 0x61, 0x74, 0x73, 0x50,
+     0x6f, 0x6c, 0x6c, 0x4d, 0x73, 0x12, 0x34, 0x0a, 0x17, 0x70, 0x72, 0x6f,
+     0x63, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x63, 0x61, 0x63, 0x68,
+     0x65, 0x5f, 0x74, 0x74, 0x6c, 0x5f, 0x6d, 0x73, 0x18, 0x06, 0x20, 0x01,
+     0x28, 0x0d, 0x52, 0x13, 0x70, 0x72, 0x6f, 0x63, 0x53, 0x74, 0x61, 0x74,
+     0x73, 0x43, 0x61, 0x63, 0x68, 0x65, 0x54, 0x74, 0x6c, 0x4d, 0x73, 0x22,
+     0x55, 0x0a, 0x06, 0x51, 0x75, 0x69, 0x72, 0x6b, 0x73, 0x12, 0x16, 0x0a,
+     0x12, 0x51, 0x55, 0x49, 0x52, 0x4b, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50,
+     0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a,
+     0x14, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x49, 0x4e, 0x49,
+     0x54, 0x49, 0x41, 0x4c, 0x5f, 0x44, 0x55, 0x4d, 0x50, 0x10, 0x01, 0x1a,
+     0x02, 0x08, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x44, 0x49, 0x53, 0x41, 0x42,
+     0x4c, 0x45, 0x5f, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4d, 0x41, 0x4e, 0x44,
+     0x10, 0x02, 0x22, 0xf3, 0x03, 0x0a, 0x0e, 0x53, 0x79, 0x73, 0x53, 0x74,
+     0x61, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2a, 0x0a,
+     0x11, 0x6d, 0x65, 0x6d, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x70, 0x65, 0x72,
+     0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d,
+     0x52, 0x0f, 0x6d, 0x65, 0x6d, 0x69, 0x6e, 0x66, 0x6f, 0x50, 0x65, 0x72,
+     0x69, 0x6f, 0x64, 0x4d, 0x73, 0x12, 0x4b, 0x0a, 0x10, 0x6d, 0x65, 0x6d,
+     0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72,
+     0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x70, 0x65,
+     0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+     0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x69, 0x6e, 0x66, 0x6f, 0x43, 0x6f, 0x75,
+     0x6e, 0x74, 0x65, 0x72, 0x73, 0x52, 0x0f, 0x6d, 0x65, 0x6d, 0x69, 0x6e,
+     0x66, 0x6f, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x28,
+     0x0a, 0x10, 0x76, 0x6d, 0x73, 0x74, 0x61, 0x74, 0x5f, 0x70, 0x65, 0x72,
+     0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d,
+     0x52, 0x0e, 0x76, 0x6d, 0x73, 0x74, 0x61, 0x74, 0x50, 0x65, 0x72, 0x69,
+     0x6f, 0x64, 0x4d, 0x73, 0x12, 0x48, 0x0a, 0x0f, 0x76, 0x6d, 0x73, 0x74,
+     0x61, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x18,
+     0x04, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x70, 0x65, 0x72, 0x66,
      0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
-     0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e,
-     0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0b,
-     0x64, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12,
-     0x60, 0x0a, 0x14, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x5f, 0x64,
-     0x61, 0x74, 0x61, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18,
-     0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70, 0x65, 0x72, 0x66,
-     0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
-     0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e,
-     0x42, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x53,
-     0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x12, 0x62, 0x75, 0x69, 0x6c, 0x74,
-     0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65,
-     0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
-     0x6e, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a,
-     0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x73, 0x12, 0x36,
-     0x0a, 0x17, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x65, 0x78, 0x74,
-     0x72, 0x61, 0x5f, 0x67, 0x75, 0x61, 0x72, 0x64, 0x72, 0x61, 0x69, 0x6c,
-     0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x65, 0x6e, 0x61,
-     0x62, 0x6c, 0x65, 0x45, 0x78, 0x74, 0x72, 0x61, 0x47, 0x75, 0x61, 0x72,
-     0x64, 0x72, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x57, 0x0a, 0x0d, 0x6c, 0x6f,
-     0x63, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18,
-     0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x70, 0x65, 0x72, 0x66,
-     0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
-     0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e,
-     0x4c, 0x6f, 0x63, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x6f, 0x64, 0x65,
-     0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x6c,
-     0x6f, 0x63, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x12,
-     0x49, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x73,
-     0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72,
+     0x56, 0x6d, 0x73, 0x74, 0x61, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65,
+     0x72, 0x73, 0x52, 0x0e, 0x76, 0x6d, 0x73, 0x74, 0x61, 0x74, 0x43, 0x6f,
+     0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x73, 0x74,
+     0x61, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73,
+     0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x73, 0x74, 0x61, 0x74,
+     0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x4d, 0x73, 0x12, 0x51, 0x0a, 0x0d,
+     0x73, 0x74, 0x61, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72,
+     0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x70, 0x65,
+     0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+     0x73, 0x2e, 0x53, 0x79, 0x73, 0x53, 0x74, 0x61, 0x74, 0x73, 0x43, 0x6f,
+     0x6e, 0x66, 0x69, 0x67, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x43, 0x6f, 0x75,
+     0x6e, 0x74, 0x65, 0x72, 0x73, 0x52, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x43,
+     0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x22, 0x7b, 0x0a, 0x0c, 0x53,
+     0x74, 0x61, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12,
+     0x14, 0x0a, 0x10, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50,
+     0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a,
+     0x0e, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x50, 0x55, 0x5f, 0x54, 0x49,
+     0x4d, 0x45, 0x53, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41,
+     0x54, 0x5f, 0x49, 0x52, 0x51, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x53,
+     0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x53,
+     0x4f, 0x46, 0x54, 0x49, 0x52, 0x51, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54,
+     0x53, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x5f,
+     0x46, 0x4f, 0x52, 0x4b, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x04,
+     0x22, 0x9e, 0x06, 0x0a, 0x0a, 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e,
+     0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x65, 0x73, 0x73, 0x61,
+     0x67, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01,
+     0x28, 0x0d, 0x52, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43,
+     0x6f, 0x75, 0x6e, 0x74, 0x12, 0x35, 0x0a, 0x17, 0x6d, 0x61, 0x78, 0x5f,
+     0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x5f, 0x70, 0x65, 0x72,
+     0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
+     0x0d, 0x52, 0x14, 0x6d, 0x61, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
+     0x65, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12,
+     0x12, 0x0a, 0x04, 0x73, 0x65, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
+     0x0d, 0x52, 0x04, 0x73, 0x65, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6d,
+     0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18,
+     0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61,
+     0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x33, 0x0a, 0x16, 0x73, 0x65,
+     0x6e, 0x64, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6f, 0x6e, 0x5f,
+     0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01,
+     0x28, 0x08, 0x52, 0x13, 0x73, 0x65, 0x6e, 0x64, 0x42, 0x61, 0x74, 0x63,
+     0x68, 0x4f, 0x6e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12,
+     0x4a, 0x0a, 0x0c, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x5f, 0x66, 0x69, 0x65,
+     0x6c, 0x64, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e,
+     0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
+     0x74, 0x6f, 0x73, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66,
+     0x69, 0x67, 0x2e, 0x44, 0x75, 0x6d, 0x6d, 0x79, 0x46, 0x69, 0x65, 0x6c,
+     0x64, 0x73, 0x52, 0x0b, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x46, 0x69, 0x65,
+     0x6c, 0x64, 0x73, 0x1a, 0xfb, 0x03, 0x0a, 0x0b, 0x44, 0x75, 0x6d, 0x6d,
+     0x79, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x66,
+     0x69, 0x65, 0x6c, 0x64, 0x5f, 0x75, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18,
+     0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64,
+     0x55, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69,
+     0x65, 0x6c, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, 0x02, 0x20,
+     0x01, 0x28, 0x05, 0x52, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x49, 0x6e,
+     0x74, 0x33, 0x32, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x69, 0x65, 0x6c, 0x64,
+     0x5f, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x03, 0x20, 0x01, 0x28,
+     0x04, 0x52, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x55, 0x69, 0x6e, 0x74,
+     0x36, 0x34, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f,
+     0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52,
+     0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x12,
+     0x23, 0x0a, 0x0d, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x66, 0x69, 0x78,
+     0x65, 0x64, 0x36, 0x34, 0x18, 0x05, 0x20, 0x01, 0x28, 0x06, 0x52, 0x0c,
+     0x66, 0x69, 0x65, 0x6c, 0x64, 0x46, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34,
+     0x12, 0x25, 0x0a, 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x73, 0x66,
+     0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x18, 0x06, 0x20, 0x01, 0x28, 0x10,
+     0x52, 0x0d, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x66, 0x69, 0x78, 0x65,
+     0x64, 0x36, 0x34, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x69, 0x65, 0x6c, 0x64,
+     0x5f, 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x18, 0x07, 0x20, 0x01,
+     0x28, 0x07, 0x52, 0x0c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x46, 0x69, 0x78,
+     0x65, 0x64, 0x33, 0x32, 0x12, 0x25, 0x0a, 0x0e, 0x66, 0x69, 0x65, 0x6c,
+     0x64, 0x5f, 0x73, 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x18, 0x08,
+     0x20, 0x01, 0x28, 0x0f, 0x52, 0x0d, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x53,
+     0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x12, 0x21, 0x0a, 0x0c, 0x66,
+     0x69, 0x65, 0x6c, 0x64, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x18,
+     0x09, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64,
+     0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69,
+     0x65, 0x6c, 0x64, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x18, 0x0a, 0x20,
+     0x01, 0x28, 0x02, 0x52, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x46, 0x6c,
+     0x6f, 0x61, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x69, 0x65, 0x6c, 0x64,
+     0x5f, 0x73, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x0b, 0x20, 0x01, 0x28,
+     0x12, 0x52, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x69, 0x6e, 0x74,
+     0x36, 0x34, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f,
+     0x73, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x11,
+     0x52, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x69, 0x6e, 0x74, 0x33,
+     0x32, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x73,
+     0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52,
+     0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67,
+     0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x79,
+     0x74, 0x65, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x66,
+     0x69, 0x65, 0x6c, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0xd1, 0x1a,
+     0x0a, 0x0b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+     0x67, 0x12, 0x43, 0x0a, 0x07, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x73,
+     0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x65, 0x72,
      0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
      0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-     0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x43, 0x6f, 0x6e,
-     0x66, 0x69, 0x67, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65,
-     0x72, 0x73, 0x12, 0x54, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64,
-     0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20,
-     0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
-     0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72,
-     0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x53, 0x74,
-     0x61, 0x74, 0x73, 0x64, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
-     0x52, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x4d, 0x65, 0x74, 0x61,
-     0x64, 0x61, 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0f, 0x77, 0x72, 0x69, 0x74,
-     0x65, 0x5f, 0x69, 0x6e, 0x74, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18,
-     0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x77, 0x72, 0x69, 0x74, 0x65,
-     0x49, 0x6e, 0x74, 0x6f, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x2f, 0x0a, 0x14,
-     0x66, 0x69, 0x6c, 0x65, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x70,
-     0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73, 0x18, 0x09, 0x20, 0x01,
-     0x28, 0x0d, 0x52, 0x11, 0x66, 0x69, 0x6c, 0x65, 0x57, 0x72, 0x69, 0x74,
-     0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x4d, 0x73, 0x12, 0x2d, 0x0a,
-     0x13, 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x73, 0x69,
-     0x7a, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01,
-     0x28, 0x04, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x46, 0x69, 0x6c, 0x65, 0x53,
-     0x69, 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x60, 0x0a, 0x13,
-     0x67, 0x75, 0x61, 0x72, 0x64, 0x72, 0x61, 0x69, 0x6c, 0x5f, 0x6f, 0x76,
-     0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28,
-     0x0b, 0x32, 0x2f, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
-     0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63,
-     0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x47, 0x75, 0x61, 0x72,
-     0x64, 0x72, 0x61, 0x69, 0x6c, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64,
-     0x65, 0x73, 0x52, 0x12, 0x67, 0x75, 0x61, 0x72, 0x64, 0x72, 0x61, 0x69,
-     0x6c, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x12, 0x25,
-     0x0a, 0x0e, 0x64, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x73,
-     0x74, 0x61, 0x72, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d,
-     0x64, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x53, 0x74, 0x61, 0x72,
-     0x74, 0x12, 0x26, 0x0a, 0x0f, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x70,
-     0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73, 0x18, 0x0d, 0x20, 0x01,
-     0x28, 0x0d, 0x52, 0x0d, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x50, 0x65, 0x72,
-     0x69, 0x6f, 0x64, 0x4d, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x66, 0x6c, 0x75,
-     0x73, 0x68, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x6d,
-     0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x66, 0x6c, 0x75,
-     0x73, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x12,
-     0x3c, 0x0a, 0x1b, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x6f, 0x75, 0x72,
-     0x63, 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65,
-     0x6f, 0x75, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0d,
-     0x52, 0x17, 0x64, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65,
-     0x53, 0x74, 0x6f, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d,
-     0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f,
-     0x74, 0x72, 0x61, 0x63, 0x65, 0x75, 0x72, 0x18, 0x10, 0x20, 0x01, 0x28,
-     0x08, 0x52, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x54, 0x72, 0x61,
-     0x63, 0x65, 0x75, 0x72, 0x12, 0x51, 0x0a, 0x0e, 0x74, 0x72, 0x69, 0x67,
-     0x67, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x11,
-     0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
+     0x2e, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+     0x67, 0x52, 0x07, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x73, 0x12, 0x4a,
+     0x0a, 0x0c, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63,
+     0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70,
+     0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+     0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66,
+     0x69, 0x67, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63,
+     0x65, 0x52, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63,
+     0x65, 0x73, 0x12, 0x60, 0x0a, 0x14, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69,
+     0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63,
+     0x65, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70,
+     0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+     0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66,
+     0x69, 0x67, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x44, 0x61,
+     0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x12, 0x62, 0x75,
+     0x69, 0x6c, 0x74, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75,
+     0x72, 0x63, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x75, 0x72, 0x61,
+     0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28,
+     0x0d, 0x52, 0x0a, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d,
+     0x73, 0x12, 0x36, 0x0a, 0x17, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f,
+     0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x67, 0x75, 0x61, 0x72, 0x64, 0x72,
+     0x61, 0x69, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15,
+     0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x78, 0x74, 0x72, 0x61, 0x47,
+     0x75, 0x61, 0x72, 0x64, 0x72, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x57, 0x0a,
+     0x0d, 0x6c, 0x6f, 0x63, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x6d, 0x6f,
+     0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x70,
+     0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+     0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66,
+     0x69, 0x67, 0x2e, 0x4c, 0x6f, 0x63, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x4d,
+     0x6f, 0x64, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+     0x52, 0x0c, 0x6c, 0x6f, 0x63, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x6f,
+     0x64, 0x65, 0x12, 0x49, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63,
+     0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e,
+     0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f,
+     0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e,
+     0x66, 0x69, 0x67, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72,
+     0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64,
+     0x75, 0x63, 0x65, 0x72, 0x73, 0x12, 0x54, 0x0a, 0x0f, 0x73, 0x74, 0x61,
+     0x74, 0x73, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
+     0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x65, 0x72,
+     0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
+     0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+     0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x64, 0x4d, 0x65, 0x74, 0x61, 0x64,
+     0x61, 0x74, 0x61, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x4d,
+     0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0f, 0x77,
+     0x72, 0x69, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x6f, 0x5f, 0x66, 0x69,
+     0x6c, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x77, 0x72,
+     0x69, 0x74, 0x65, 0x49, 0x6e, 0x74, 0x6f, 0x46, 0x69, 0x6c, 0x65, 0x12,
+     0x2f, 0x0a, 0x14, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x77, 0x72, 0x69, 0x74,
+     0x65, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73, 0x18,
+     0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x66, 0x69, 0x6c, 0x65, 0x57,
+     0x72, 0x69, 0x74, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x4d, 0x73,
+     0x12, 0x2d, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x69, 0x6c, 0x65,
+     0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18,
+     0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x46, 0x69,
+     0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12,
+     0x60, 0x0a, 0x13, 0x67, 0x75, 0x61, 0x72, 0x64, 0x72, 0x61, 0x69, 0x6c,
+     0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x18, 0x0b,
+     0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
      0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54,
-     0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54,
-     0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-     0x52, 0x0d, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x43, 0x6f, 0x6e,
-     0x66, 0x69, 0x67, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x63, 0x74, 0x69, 0x76,
-     0x61, 0x74, 0x65, 0x5f, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73,
-     0x18, 0x12, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x63, 0x74, 0x69,
-     0x76, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73,
-     0x12, 0x6d, 0x0a, 0x18, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e,
-     0x74, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x6f,
-     0x6e, 0x66, 0x69, 0x67, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33,
-     0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72,
-     0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f,
-     0x6e, 0x66, 0x69, 0x67, 0x2e, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65,
-     0x6e, 0x74, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e,
-     0x66, 0x69, 0x67, 0x52, 0x16, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65,
-     0x6e, 0x74, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e,
-     0x66, 0x69, 0x67, 0x12, 0x37, 0x0a, 0x18, 0x61, 0x6c, 0x6c, 0x6f, 0x77,
-     0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f,
-     0x74, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x13, 0x20, 0x01, 0x28,
-     0x08, 0x52, 0x15, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x55, 0x73, 0x65, 0x72,
-     0x42, 0x75, 0x69, 0x6c, 0x64, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67,
-     0x12, 0x2e, 0x0a, 0x13, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x5f, 0x73,
-     0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18,
-     0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x75, 0x6e, 0x69, 0x71, 0x75,
-     0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65,
-     0x12, 0x57, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73,
-     0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x18, 0x20, 0x01,
-     0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
-     0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61,
-     0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x6f, 0x6d,
-     0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65,
-     0x52, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f,
-     0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x67, 0x0a, 0x16, 0x69, 0x6e, 0x63,
-     0x69, 0x64, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74,
-     0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x19, 0x20, 0x01, 0x28,
-     0x0b, 0x32, 0x31, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
+     0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x47,
+     0x75, 0x61, 0x72, 0x64, 0x72, 0x61, 0x69, 0x6c, 0x4f, 0x76, 0x65, 0x72,
+     0x72, 0x69, 0x64, 0x65, 0x73, 0x52, 0x12, 0x67, 0x75, 0x61, 0x72, 0x64,
+     0x72, 0x61, 0x69, 0x6c, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65,
+     0x73, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65,
+     0x64, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28,
+     0x08, 0x52, 0x0d, 0x64, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x53,
+     0x74, 0x61, 0x72, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x66, 0x6c, 0x75, 0x73,
+     0x68, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73, 0x18,
+     0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x66, 0x6c, 0x75, 0x73, 0x68,
+     0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x4d, 0x73, 0x12, 0x28, 0x0a, 0x10,
+     0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75,
+     0x74, 0x5f, 0x6d, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e,
+     0x66, 0x6c, 0x75, 0x73, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74,
+     0x4d, 0x73, 0x12, 0x3c, 0x0a, 0x1b, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73,
+     0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x74,
+     0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x17, 0x20,
+     0x01, 0x28, 0x0d, 0x52, 0x17, 0x64, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75,
+     0x72, 0x63, 0x65, 0x53, 0x74, 0x6f, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x6f,
+     0x75, 0x74, 0x4d, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69,
+     0x66, 0x79, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x75, 0x72, 0x18, 0x10,
+     0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79,
+     0x54, 0x72, 0x61, 0x63, 0x65, 0x75, 0x72, 0x12, 0x51, 0x0a, 0x0e, 0x74,
+     0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+     0x67, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x65,
+     0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+     0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+     0x67, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x43, 0x6f, 0x6e,
+     0x66, 0x69, 0x67, 0x52, 0x0d, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72,
+     0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x63,
+     0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x72, 0x69, 0x67, 0x67,
+     0x65, 0x72, 0x73, 0x18, 0x12, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61,
+     0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67,
+     0x65, 0x72, 0x73, 0x12, 0x6d, 0x0a, 0x18, 0x69, 0x6e, 0x63, 0x72, 0x65,
+     0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65,
+     0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x15, 0x20, 0x01, 0x28,
+     0x0b, 0x32, 0x33, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
      0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63,
-     0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x49, 0x6e, 0x63, 0x69,
-     0x64, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f,
-     0x6e, 0x66, 0x69, 0x67, 0x52, 0x14, 0x69, 0x6e, 0x63, 0x69, 0x64, 0x65,
-     0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66,
-     0x69, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f,
-     0x75, 0x75, 0x69, 0x64, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
-     0x74, 0x72, 0x61, 0x63, 0x65, 0x55, 0x75, 0x69, 0x64, 0x1a, 0xc7, 0x01,
-     0x0a, 0x0c, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66,
-     0x69, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x6b,
-     0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x69, 0x7a,
-     0x65, 0x4b, 0x62, 0x12, 0x55, 0x0a, 0x0b, 0x66, 0x69, 0x6c, 0x6c, 0x5f,
-     0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e,
-     0x32, 0x34, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e,
-     0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65,
-     0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x42, 0x75, 0x66, 0x66, 0x65,
-     0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x46, 0x69, 0x6c, 0x6c,
-     0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x6c,
-     0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x3b, 0x0a, 0x0a, 0x46, 0x69,
-     0x6c, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x0f, 0x0a, 0x0b,
-     0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
-     0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x42, 0x55,
-     0x46, 0x46, 0x45, 0x52, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x49,
-     0x53, 0x43, 0x41, 0x52, 0x44, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10,
-     0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x1a, 0x79, 0x0a, 0x0a, 0x44,
-     0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x39, 0x0a,
-     0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28,
-     0x0b, 0x32, 0x21, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
-     0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61,
-     0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-     0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x30, 0x0a, 0x14,
-     0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d,
-     0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x03,
-     0x28, 0x09, 0x52, 0x12, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72,
-     0x4e, 0x61, 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0xb3,
-     0x01, 0x0a, 0x11, 0x42, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x44, 0x61,
-     0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x3c, 0x0a, 0x1a,
-     0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6c, 0x6f, 0x63,
-     0x6b, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x74, 0x69,
-     0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x64, 0x69,
-     0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x6e,
-     0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x30,
-     0x0a, 0x14, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x72,
-     0x61, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02,
-     0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c,
-     0x65, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-     0x12, 0x2e, 0x0a, 0x13, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f,
-     0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18,
-     0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x64, 0x69, 0x73, 0x61, 0x62,
-     0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f,
-     0x1a, 0x77, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72,
-     0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72,
-     0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18,
-     0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x64, 0x75,
-     0x63, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0b, 0x73,
-     0x68, 0x6d, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x6b, 0x62, 0x18, 0x02,
-     0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x73, 0x68, 0x6d, 0x53, 0x69, 0x7a,
-     0x65, 0x4b, 0x62, 0x12, 0x20, 0x0a, 0x0c, 0x70, 0x61, 0x67, 0x65, 0x5f,
-     0x73, 0x69, 0x7a, 0x65, 0x5f, 0x6b, 0x62, 0x18, 0x03, 0x20, 0x01, 0x28,
-     0x0d, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x4b,
-     0x62, 0x1a, 0xe4, 0x01, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x64,
-     0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2e, 0x0a, 0x13,
-     0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x61,
-     0x6c, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
-     0x03, 0x52, 0x11, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e,
-     0x67, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x15,
-     0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x63,
-     0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20,
-     0x01, 0x28, 0x05, 0x52, 0x13, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72,
-     0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x55, 0x69, 0x64,
-     0x12, 0x30, 0x0a, 0x14, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69,
-     0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64,
-     0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x74, 0x72, 0x69, 0x67,
+     0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x49, 0x6e, 0x63, 0x72,
+     0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65,
+     0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x16, 0x69, 0x6e, 0x63, 0x72,
+     0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65,
+     0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x37, 0x0a, 0x18, 0x61, 0x6c,
+     0x6c, 0x6f, 0x77, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x62, 0x75, 0x69,
+     0x6c, 0x64, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x13,
+     0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x55,
+     0x73, 0x65, 0x72, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x54, 0x72, 0x61, 0x63,
+     0x69, 0x6e, 0x67, 0x12, 0x2e, 0x0a, 0x13, 0x75, 0x6e, 0x69, 0x71, 0x75,
+     0x65, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61,
+     0x6d, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x75, 0x6e,
+     0x69, 0x71, 0x75, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4e,
+     0x61, 0x6d, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x72,
+     0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18,
+     0x18, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x70, 0x65, 0x72, 0x66,
+     0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
+     0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e,
+     0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54,
+     0x79, 0x70, 0x65, 0x52, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73,
+     0x73, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x67, 0x0a, 0x16,
+     0x69, 0x6e, 0x63, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x70,
+     0x6f, 0x72, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x19,
+     0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
+     0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54,
+     0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x49,
+     0x6e, 0x63, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72,
+     0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x14, 0x69, 0x6e, 0x63,
+     0x69, 0x64, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43,
+     0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x72, 0x61,
+     0x63, 0x65, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x1a, 0x20, 0x01, 0x28,
+     0x0c, 0x52, 0x09, 0x74, 0x72, 0x61, 0x63, 0x65, 0x55, 0x75, 0x69, 0x64,
+     0x1a, 0xc7, 0x01, 0x0a, 0x0c, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x43,
+     0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x69, 0x7a,
+     0x65, 0x5f, 0x6b, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06,
+     0x73, 0x69, 0x7a, 0x65, 0x4b, 0x62, 0x12, 0x55, 0x0a, 0x0b, 0x66, 0x69,
+     0x6c, 0x6c, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x04, 0x20,
+     0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74,
+     0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72,
+     0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x42, 0x75,
+     0x66, 0x66, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x46,
+     0x69, 0x6c, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x0a, 0x66,
+     0x69, 0x6c, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x3b, 0x0a,
+     0x0a, 0x46, 0x69, 0x6c, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12,
+     0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
+     0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x49, 0x4e, 0x47,
+     0x5f, 0x42, 0x55, 0x46, 0x46, 0x45, 0x52, 0x10, 0x01, 0x12, 0x0b, 0x0a,
+     0x07, 0x44, 0x49, 0x53, 0x43, 0x41, 0x52, 0x44, 0x10, 0x02, 0x4a, 0x04,
+     0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x1a, 0x79,
+     0x0a, 0x0a, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65,
+     0x12, 0x39, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01,
+     0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
+     0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x44,
+     0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e,
+     0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
+     0x30, 0x0a, 0x14, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x5f,
+     0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18,
+     0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x70, 0x72, 0x6f, 0x64, 0x75,
+     0x63, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65,
+     0x72, 0x1a, 0xb3, 0x01, 0x0a, 0x11, 0x42, 0x75, 0x69, 0x6c, 0x74, 0x69,
+     0x6e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12,
+     0x3c, 0x0a, 0x1a, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63,
+     0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f,
+     0x74, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
+     0x18, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6c, 0x6f, 0x63,
+     0x6b, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x74, 0x69, 0x6e,
+     0x67, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65,
+     0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+     0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, 0x69, 0x73,
+     0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e,
+     0x66, 0x69, 0x67, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x69, 0x73, 0x61, 0x62,
+     0x6c, 0x65, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x6e,
+     0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x64, 0x69,
+     0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49,
+     0x6e, 0x66, 0x6f, 0x1a, 0x77, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x64, 0x75,
+     0x63, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a,
+     0x0d, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x5f, 0x6e, 0x61,
+     0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72,
+     0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e,
+     0x0a, 0x0b, 0x73, 0x68, 0x6d, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x6b,
+     0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x73, 0x68, 0x6d,
+     0x53, 0x69, 0x7a, 0x65, 0x4b, 0x62, 0x12, 0x20, 0x0a, 0x0c, 0x70, 0x61,
+     0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x6b, 0x62, 0x18, 0x03,
+     0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69,
+     0x7a, 0x65, 0x4b, 0x62, 0x1a, 0xe4, 0x01, 0x0a, 0x0e, 0x53, 0x74, 0x61,
+     0x74, 0x73, 0x64, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12,
+     0x2e, 0x0a, 0x13, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e,
+     0x67, 0x5f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01,
+     0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65,
+     0x72, 0x69, 0x6e, 0x67, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x49, 0x64, 0x12,
+     0x32, 0x0a, 0x15, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e,
+     0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75, 0x69, 0x64,
+     0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x13, 0x74, 0x72, 0x69, 0x67,
      0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-     0x49, 0x64, 0x12, 0x3c, 0x0a, 0x1a, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65,
-     0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
-     0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01,
-     0x28, 0x03, 0x52, 0x18, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69,
-     0x6e, 0x67, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
-     0x6f, 0x6e, 0x49, 0x64, 0x1a, 0x4c, 0x0a, 0x12, 0x47, 0x75, 0x61, 0x72,
-     0x64, 0x72, 0x61, 0x69, 0x6c, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64,
-     0x65, 0x73, 0x12, 0x36, 0x0a, 0x18, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x70,
-     0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x79,
-     0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
-     0x52, 0x14, 0x6d, 0x61, 0x78, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x50,
-     0x65, 0x72, 0x44, 0x61, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0xa0,
-     0x03, 0x0a, 0x0d, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x43, 0x6f,
-     0x6e, 0x66, 0x69, 0x67, 0x12, 0x59, 0x0a, 0x0c, 0x74, 0x72, 0x69, 0x67,
-     0x67, 0x65, 0x72, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01,
-     0x28, 0x0e, 0x32, 0x36, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74,
-     0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61,
-     0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x72, 0x69,
-     0x67, 0x67, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54,
-     0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0b,
-     0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x12,
-     0x4e, 0x0a, 0x08, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x18,
-     0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x70, 0x65, 0x72, 0x66,
+     0x55, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x72, 0x69, 0x67, 0x67,
+     0x65, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+     0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x74,
+     0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e,
+     0x66, 0x69, 0x67, 0x49, 0x64, 0x12, 0x3c, 0x0a, 0x1a, 0x74, 0x72, 0x69,
+     0x67, 0x67, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x75, 0x62, 0x73,
+     0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18,
+     0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x18, 0x74, 0x72, 0x69, 0x67, 0x67,
+     0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
+     0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x1a, 0x4c, 0x0a, 0x12, 0x47,
+     0x75, 0x61, 0x72, 0x64, 0x72, 0x61, 0x69, 0x6c, 0x4f, 0x76, 0x65, 0x72,
+     0x72, 0x69, 0x64, 0x65, 0x73, 0x12, 0x36, 0x0a, 0x18, 0x6d, 0x61, 0x78,
+     0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x5f,
+     0x64, 0x61, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20,
+     0x01, 0x28, 0x04, 0x52, 0x14, 0x6d, 0x61, 0x78, 0x55, 0x70, 0x6c, 0x6f,
+     0x61, 0x64, 0x50, 0x65, 0x72, 0x44, 0x61, 0x79, 0x42, 0x79, 0x74, 0x65,
+     0x73, 0x1a, 0xa0, 0x03, 0x0a, 0x0d, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65,
+     0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x59, 0x0a, 0x0c, 0x74,
+     0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18,
+     0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x70, 0x65, 0x72, 0x66,
      0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
      0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e,
      0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69,
-     0x67, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x08, 0x74,
-     0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x74,
-     0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f,
-     0x75, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52,
-     0x10, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65,
-     0x6f, 0x75, 0x74, 0x4d, 0x73, 0x1a, 0x71, 0x0a, 0x07, 0x54, 0x72, 0x69,
-     0x67, 0x67, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
-     0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
-     0x12, 0x2e, 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72,
-     0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18,
-     0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x70, 0x72, 0x6f, 0x64, 0x75,
-     0x63, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x67, 0x65, 0x78,
-     0x12, 0x22, 0x0a, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x64, 0x65, 0x6c,
-     0x61, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52,
-     0x0b, 0x73, 0x74, 0x6f, 0x70, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x73,
-     0x22, 0x43, 0x0a, 0x0b, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x4d,
-     0x6f, 0x64, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45,
-     0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d,
-     0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x54, 0x52, 0x41, 0x43, 0x49, 0x4e,
-     0x47, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x4f, 0x50, 0x5f,
-     0x54, 0x52, 0x41, 0x43, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x1a, 0x40, 0x0a,
-     0x16, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c,
-     0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
-     0x26, 0x0a, 0x0f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x70, 0x65, 0x72,
-     0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d,
-     0x52, 0x0d, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x50, 0x65, 0x72, 0x69, 0x6f,
-     0x64, 0x4d, 0x73, 0x1a, 0xbc, 0x01, 0x0a, 0x14, 0x49, 0x6e, 0x63, 0x69,
-     0x64, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f,
-     0x6e, 0x66, 0x69, 0x67, 0x12, 0x2f, 0x0a, 0x13, 0x64, 0x65, 0x73, 0x74,
-     0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x63, 0x6b,
-     0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x64,
-     0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61,
-     0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x65, 0x73,
-     0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6c, 0x61,
-     0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x65,
-     0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x61,
-     0x73, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63,
-     0x79, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28,
-     0x05, 0x52, 0x0c, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x4c, 0x65,
-     0x76, 0x65, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x5f,
-     0x64, 0x72, 0x6f, 0x70, 0x62, 0x6f, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28,
-     0x08, 0x52, 0x0b, 0x73, 0x6b, 0x69, 0x70, 0x44, 0x72, 0x6f, 0x70, 0x62,
-     0x6f, 0x78, 0x22, 0x55, 0x0a, 0x15, 0x4c, 0x6f, 0x63, 0x6b, 0x64, 0x6f,
-     0x77, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74,
-     0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x12, 0x4c, 0x4f, 0x43, 0x4b, 0x44,
-     0x4f, 0x57, 0x4e, 0x5f, 0x55, 0x4e, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45,
-     0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x4f, 0x43, 0x4b, 0x44,
-     0x4f, 0x57, 0x4e, 0x5f, 0x43, 0x4c, 0x45, 0x41, 0x52, 0x10, 0x01, 0x12,
-     0x10, 0x0a, 0x0c, 0x4c, 0x4f, 0x43, 0x4b, 0x44, 0x4f, 0x57, 0x4e, 0x5f,
-     0x53, 0x45, 0x54, 0x10, 0x02, 0x22, 0x51, 0x0a, 0x0f, 0x43, 0x6f, 0x6d,
-     0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65,
-     0x12, 0x20, 0x0a, 0x1c, 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53,
-     0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53,
-     0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c,
-     0x0a, 0x18, 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x49, 0x4f,
-     0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x45, 0x46, 0x4c, 0x41,
-     0x54, 0x45, 0x10, 0x01, 0x4a, 0x04, 0x08, 0x0f, 0x10, 0x10, 0x22, 0xed,
-     0x04, 0x0a, 0x0f, 0x48, 0x65, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x66, 0x64,
-     0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x36, 0x0a, 0x17, 0x73, 0x61,
-     0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72,
-     0x76, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20,
-     0x01, 0x28, 0x04, 0x52, 0x15, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e,
-     0x67, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x42, 0x79, 0x74,
-     0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73,
-     0x73, 0x5f, 0x63, 0x6d, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x02, 0x20,
-     0x03, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
-     0x43, 0x6d, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x70,
-     0x69, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x04, 0x52, 0x03, 0x70, 0x69,
-     0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x05, 0x20, 0x01,
-     0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x2c, 0x0a, 0x12, 0x73,
-     0x6b, 0x69, 0x70, 0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x5f, 0x70,
-     0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52,
-     0x10, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x50,
-     0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x6b, 0x0a, 0x16, 0x63, 0x6f, 0x6e,
-     0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x64, 0x75, 0x6d, 0x70,
-     0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28,
-     0x0b, 0x32, 0x35, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
-     0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x70,
-     0x70, 0x72, 0x6f, 0x66, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e,
-     0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x44, 0x75,
-     0x6d, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x14, 0x63, 0x6f,
-     0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x44, 0x75, 0x6d, 0x70,
-     0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x68,
-     0x6d, 0x65, 0x6d, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x62, 0x79, 0x74,
-     0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x73, 0x68,
-     0x6d, 0x65, 0x6d, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73,
-     0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x63, 0x6c,
-     0x69, 0x65, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b,
-     0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12,
-     0x1d, 0x0a, 0x0a, 0x6e, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75,
-     0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6e, 0x6f, 0x53,
-     0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x6f,
-     0x5f, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x0b, 0x20, 0x01,
-     0x28, 0x08, 0x52, 0x09, 0x6e, 0x6f, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e,
-     0x67, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x64, 0x6c, 0x65, 0x5f, 0x61, 0x6c,
-     0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0c, 0x20,
-     0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x64, 0x6c, 0x65, 0x41, 0x6c, 0x6c,
-     0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x0b,
-     0x64, 0x75, 0x6d, 0x70, 0x5f, 0x61, 0x74, 0x5f, 0x6d, 0x61, 0x78, 0x18,
-     0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x64, 0x75, 0x6d, 0x70, 0x41,
-     0x74, 0x4d, 0x61, 0x78, 0x1a, 0x64, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x74,
-     0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x44, 0x75, 0x6d, 0x70, 0x43, 0x6f,
-     0x6e, 0x66, 0x69, 0x67, 0x12, 0x22, 0x0a, 0x0d, 0x64, 0x75, 0x6d, 0x70,
-     0x5f, 0x70, 0x68, 0x61, 0x73, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x05, 0x20,
-     0x01, 0x28, 0x0d, 0x52, 0x0b, 0x64, 0x75, 0x6d, 0x70, 0x50, 0x68, 0x61,
-     0x73, 0x65, 0x4d, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x64, 0x75, 0x6d, 0x70,
-     0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x6d, 0x73,
-     0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x64, 0x75, 0x6d, 0x70,
-     0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x73, 0x22, 0x9f,
-     0x02, 0x0a, 0x0f, 0x4a, 0x61, 0x76, 0x61, 0x48, 0x70, 0x72, 0x6f, 0x66,
-     0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x72,
-     0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6d, 0x64, 0x6c, 0x69, 0x6e,
-     0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x72, 0x6f,
-     0x63, 0x65, 0x73, 0x73, 0x43, 0x6d, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12,
-     0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04,
-     0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x6b, 0x0a, 0x16, 0x63, 0x6f, 0x6e,
-     0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x64, 0x75, 0x6d, 0x70,
-     0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28,
-     0x0b, 0x32, 0x35, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f,
-     0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4a, 0x61, 0x76, 0x61,
-     0x48, 0x70, 0x72, 0x6f, 0x66, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e,
-     0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x44, 0x75,
-     0x6d, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x14, 0x63, 0x6f,
-     0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x44, 0x75, 0x6d, 0x70,
-     0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x64, 0x0a, 0x14, 0x43, 0x6f,
-     0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x44, 0x75, 0x6d, 0x70,
-     0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x22, 0x0a, 0x0d, 0x64, 0x75,
-     0x6d, 0x70, 0x5f, 0x70, 0x68, 0x61, 0x73, 0x65, 0x5f, 0x6d, 0x73, 0x18,
-     0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x64, 0x75, 0x6d, 0x70, 0x50,
-     0x68, 0x61, 0x73, 0x65, 0x4d, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x64, 0x75,
-     0x6d, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f,
-     0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x64, 0x75,
-     0x6d, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x73,
-     0x22, 0xb8, 0x01, 0x0a, 0x10, 0x47, 0x70, 0x75, 0x43, 0x6f, 0x75, 0x6e,
-     0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2a, 0x0a,
-     0x11, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x65, 0x72,
-     0x69, 0x6f, 0x64, 0x5f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
-     0x52, 0x0f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x50, 0x65, 0x72,
-     0x69, 0x6f, 0x64, 0x4e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x75,
-     0x6e, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03,
-     0x28, 0x0d, 0x52, 0x0a, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x49,
-     0x64, 0x73, 0x12, 0x33, 0x0a, 0x15, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75,
-     0x6d, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c,
-     0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x69,
-     0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x53,
-     0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x12, 0x22, 0x0a, 0x0d, 0x66,
-     0x69, 0x78, 0x5f, 0x67, 0x70, 0x75, 0x5f, 0x63, 0x6c, 0x6f, 0x63, 0x6b,
-     0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x66, 0x69, 0x78, 0x47,
-     0x70, 0x75, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x44, 0x0a, 0x12, 0x50,
-     0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x43,
-     0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x61, 0x63,
-     0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x69,
-     0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11,
-     0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x46,
-     0x69, 0x6c, 0x74, 0x65, 0x72, 0x2a, 0x8e, 0x01, 0x0a, 0x0c, 0x41, 0x6e,
-     0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6f, 0x67, 0x49, 0x64, 0x12, 0x0f,
-     0x0a, 0x0b, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c,
-     0x54, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x49, 0x44, 0x5f, 0x52,
-     0x41, 0x44, 0x49, 0x4f, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x49,
-     0x44, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x53, 0x10, 0x02, 0x12, 0x0e,
-     0x0a, 0x0a, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d,
-     0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x52,
-     0x41, 0x53, 0x48, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x49, 0x44,
-     0x5f, 0x53, 0x54, 0x41, 0x54, 0x53, 0x10, 0x05, 0x12, 0x10, 0x0a, 0x0c,
-     0x4c, 0x49, 0x44, 0x5f, 0x53, 0x45, 0x43, 0x55, 0x52, 0x49, 0x54, 0x59,
-     0x10, 0x06, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x49, 0x44, 0x5f, 0x4b, 0x45,
-     0x52, 0x4e, 0x45, 0x4c, 0x10, 0x07, 0x2a, 0x9b, 0x01, 0x0a, 0x12, 0x41,
-     0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6f, 0x67, 0x50, 0x72, 0x69,
-     0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x52, 0x49,
-     0x4f, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45,
-     0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x52, 0x49, 0x4f, 0x5f,
-     0x55, 0x4e, 0x55, 0x53, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c,
-     0x50, 0x52, 0x49, 0x4f, 0x5f, 0x56, 0x45, 0x52, 0x42, 0x4f, 0x53, 0x45,
-     0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x44,
-     0x45, 0x42, 0x55, 0x47, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x50, 0x52,
-     0x49, 0x4f, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x04, 0x12, 0x0d, 0x0a,
-     0x09, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x10, 0x05,
-     0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x45, 0x52, 0x52,
-     0x4f, 0x52, 0x10, 0x06, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x49, 0x4f,
-     0x5f, 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, 0x07, 0x2a, 0xbf, 0x06, 0x0a,
-     0x0f, 0x4d, 0x65, 0x6d, 0x69, 0x6e, 0x66, 0x6f, 0x43, 0x6f, 0x75, 0x6e,
-     0x74, 0x65, 0x72, 0x73, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49,
-     0x4e, 0x46, 0x4f, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46,
-     0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d,
-     0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x5f, 0x54, 0x4f, 0x54,
-     0x41, 0x4c, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x45, 0x4d, 0x49,
-     0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x5f, 0x46, 0x52, 0x45, 0x45,
-     0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
-     0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x5f, 0x41, 0x56, 0x41, 0x49, 0x4c, 0x41,
-     0x42, 0x4c, 0x45, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x45, 0x4d,
-     0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x42, 0x55, 0x46, 0x46, 0x45, 0x52, 0x53,
-     0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
-     0x4f, 0x5f, 0x43, 0x41, 0x43, 0x48, 0x45, 0x44, 0x10, 0x05, 0x12, 0x17,
-     0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x57,
-     0x41, 0x50, 0x5f, 0x43, 0x41, 0x43, 0x48, 0x45, 0x44, 0x10, 0x06, 0x12,
-     0x12, 0x0a, 0x0e, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x41,
-     0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x07, 0x12, 0x14, 0x0a, 0x10, 0x4d,
-     0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54,
-     0x49, 0x56, 0x45, 0x10, 0x08, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d,
-     0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f,
-     0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x09, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45,
-     0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49,
-     0x56, 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x0a, 0x12, 0x17, 0x0a,
-     0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x41, 0x43, 0x54,
-     0x49, 0x56, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x0b, 0x12, 0x19,
-     0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x49, 0x4e,
+     0x67, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x4d, 0x6f, 0x64,
+     0x65, 0x52, 0x0b, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x4d, 0x6f,
+     0x64, 0x65, 0x12, 0x4e, 0x0a, 0x08, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65,
+     0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x70,
+     0x65, 0x72, 0x66, 0x65, 0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+     0x6f, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66,
+     0x69, 0x67, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x43, 0x6f,
+     0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72,
+     0x52, 0x08, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x12, 0x2c,
+     0x0a, 0x12, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x5f, 0x74, 0x69,
+     0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01,
+     0x28, 0x0d, 0x52, 0x10, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x54,
+     0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x1a, 0x71, 0x0a, 0x07,
+     0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e,
+     0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
+     0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x64, 0x75,
+     0x63, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x72, 0x65, 0x67,
+     0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x70, 0x72,
+     0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65,
+     0x67, 0x65, 0x78, 0x12, 0x22, 0x0a, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x5f,
+     0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01,
+     0x28, 0x0d, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x70, 0x44, 0x65, 0x6c, 0x61,
+     0x79, 0x4d, 0x73, 0x22, 0x43, 0x0a, 0x0b, 0x54, 0x72, 0x69, 0x67, 0x67,
+     0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e,
+     0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12,
+     0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x54, 0x52, 0x41,
+     0x43, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54,
+     0x4f, 0x50, 0x5f, 0x54, 0x52, 0x41, 0x43, 0x49, 0x4e, 0x47, 0x10, 0x02,
+     0x1a, 0x40, 0x0a, 0x16, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e,
+     0x74, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66,
+     0x69, 0x67, 0x12, 0x26, 0x0a, 0x0f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f,
+     0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73, 0x18, 0x01, 0x20,
+     0x01, 0x28, 0x0d, 0x52, 0x0d, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x50, 0x65,
+     0x72, 0x69, 0x6f, 0x64, 0x4d, 0x73, 0x1a, 0xbc, 0x01, 0x0a, 0x14, 0x49,
+     0x6e, 0x63, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72,
+     0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2f, 0x0a, 0x13, 0x64,
+     0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70,
+     0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+     0x52, 0x12, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f,
+     0x6e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x2b, 0x0a, 0x11,
+     0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
+     0x63, 0x6c, 0x61, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+     0x10, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+     0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x69,
+     0x76, 0x61, 0x63, 0x79, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03,
+     0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63,
+     0x79, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6b,
+     0x69, 0x70, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x62, 0x6f, 0x78, 0x18, 0x04,
+     0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x73, 0x6b, 0x69, 0x70, 0x44, 0x72,
+     0x6f, 0x70, 0x62, 0x6f, 0x78, 0x22, 0x55, 0x0a, 0x15, 0x4c, 0x6f, 0x63,
+     0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x4f, 0x70, 0x65,
+     0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x12, 0x4c, 0x4f,
+     0x43, 0x4b, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x55, 0x4e, 0x43, 0x48, 0x41,
+     0x4e, 0x47, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x4f,
+     0x43, 0x4b, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x43, 0x4c, 0x45, 0x41, 0x52,
+     0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x4f, 0x43, 0x4b, 0x44, 0x4f,
+     0x57, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x10, 0x02, 0x22, 0x51, 0x0a, 0x0f,
+     0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54,
+     0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x1c, 0x43, 0x4f, 0x4d, 0x50, 0x52,
+     0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f,
+     0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
+     0x00, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53,
+     0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x45,
+     0x46, 0x4c, 0x41, 0x54, 0x45, 0x10, 0x01, 0x4a, 0x04, 0x08, 0x0f, 0x10,
+     0x10, 0x22, 0xed, 0x04, 0x0a, 0x0f, 0x48, 0x65, 0x61, 0x70, 0x70, 0x72,
+     0x6f, 0x66, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x36, 0x0a,
+     0x17, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e,
+     0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73,
+     0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x15, 0x73, 0x61, 0x6d, 0x70,
+     0x6c, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c,
+     0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x72, 0x6f,
+     0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6d, 0x64, 0x6c, 0x69, 0x6e, 0x65,
+     0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x63,
+     0x65, 0x73, 0x73, 0x43, 0x6d, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x10,
+     0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x04, 0x52,
+     0x03, 0x70, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18,
+     0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x2c,
+     0x0a, 0x12, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f,
+     0x6c, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x07, 0x20, 0x03,
+     0x28, 0x09, 0x52, 0x10, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x79, 0x6d, 0x62,
+     0x6f, 0x6c, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x6b, 0x0a, 0x16,
+     0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x64,
+     0x75, 0x6d, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06,
+     0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
+     0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48,
+     0x65, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x66, 0x64, 0x43, 0x6f, 0x6e, 0x66,
+     0x69, 0x67, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75,
+     0x73, 0x44, 0x75, 0x6d, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
+     0x14, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x44,
+     0x75, 0x6d, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, 0x0a,
+     0x10, 0x73, 0x68, 0x6d, 0x65, 0x6d, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f,
+     0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52,
+     0x0e, 0x73, 0x68, 0x6d, 0x65, 0x6d, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x79,
+     0x74, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
+     0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28,
+     0x08, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x43, 0x6c, 0x69, 0x65,
+     0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x6f, 0x5f, 0x73, 0x74, 0x61,
+     0x72, 0x74, 0x75, 0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09,
+     0x6e, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x1d, 0x0a,
+     0x0a, 0x6e, 0x6f, 0x5f, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18,
+     0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6e, 0x6f, 0x52, 0x75, 0x6e,
+     0x6e, 0x69, 0x6e, 0x67, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x64, 0x6c, 0x65,
+     0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+     0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x64, 0x6c, 0x65,
+     0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12,
+     0x1e, 0x0a, 0x0b, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x61, 0x74, 0x5f, 0x6d,
+     0x61, 0x78, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x64, 0x75,
+     0x6d, 0x70, 0x41, 0x74, 0x4d, 0x61, 0x78, 0x1a, 0x64, 0x0a, 0x14, 0x43,
+     0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x44, 0x75, 0x6d,
+     0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x22, 0x0a, 0x0d, 0x64,
+     0x75, 0x6d, 0x70, 0x5f, 0x70, 0x68, 0x61, 0x73, 0x65, 0x5f, 0x6d, 0x73,
+     0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x64, 0x75, 0x6d, 0x70,
+     0x50, 0x68, 0x61, 0x73, 0x65, 0x4d, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x64,
+     0x75, 0x6d, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c,
+     0x5f, 0x6d, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x64,
+     0x75, 0x6d, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d,
+     0x73, 0x22, 0x9f, 0x02, 0x0a, 0x0f, 0x4a, 0x61, 0x76, 0x61, 0x48, 0x70,
+     0x72, 0x6f, 0x66, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x27, 0x0a,
+     0x0f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6d, 0x64,
+     0x6c, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e,
+     0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6d, 0x64, 0x6c, 0x69,
+     0x6e, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x02, 0x20,
+     0x03, 0x28, 0x04, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x6b, 0x0a, 0x16,
+     0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x5f, 0x64,
+     0x75, 0x6d, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03,
+     0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x70, 0x65, 0x72, 0x66, 0x65,
+     0x74, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4a,
+     0x61, 0x76, 0x61, 0x48, 0x70, 0x72, 0x6f, 0x66, 0x43, 0x6f, 0x6e, 0x66,
+     0x69, 0x67, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75,
+     0x73, 0x44, 0x75, 0x6d, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
+     0x14, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x44,
+     0x75, 0x6d, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x64, 0x0a,
+     0x14, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x6f, 0x75, 0x73, 0x44,
+     0x75, 0x6d, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x22, 0x0a,
+     0x0d, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x70, 0x68, 0x61, 0x73, 0x65, 0x5f,
+     0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x64, 0x75,
+     0x6d, 0x70, 0x50, 0x68, 0x61, 0x73, 0x65, 0x4d, 0x73, 0x12, 0x28, 0x0a,
+     0x10, 0x64, 0x75, 0x6d, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76,
+     0x61, 0x6c, 0x5f, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52,
+     0x0e, 0x64, 0x75, 0x6d, 0x70, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61,
+     0x6c, 0x4d, 0x73, 0x22, 0xb8, 0x01, 0x0a, 0x10, 0x47, 0x70, 0x75, 0x43,
+     0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+     0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f,
+     0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x6e, 0x73, 0x18, 0x01, 0x20,
+     0x01, 0x28, 0x04, 0x52, 0x0f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72,
+     0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x4e, 0x73, 0x12, 0x1f, 0x0a, 0x0b,
+     0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18,
+     0x02, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0a, 0x63, 0x6f, 0x75, 0x6e, 0x74,
+     0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x33, 0x0a, 0x15, 0x69, 0x6e, 0x73,
+     0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x61,
+     0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
+     0x52, 0x14, 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74,
+     0x65, 0x64, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x12, 0x22,
+     0x0a, 0x0d, 0x66, 0x69, 0x78, 0x5f, 0x67, 0x70, 0x75, 0x5f, 0x63, 0x6c,
+     0x6f, 0x63, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x66,
+     0x69, 0x78, 0x47, 0x70, 0x75, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x44,
+     0x0a, 0x12, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x4c, 0x69,
+     0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2e, 0x0a, 0x13,
+     0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
+     0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28,
+     0x09, 0x52, 0x11, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4e, 0x61,
+     0x6d, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2a, 0x8e, 0x01, 0x0a,
+     0x0c, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6f, 0x67, 0x49,
+     0x64, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x45, 0x46,
+     0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x49,
+     0x44, 0x5f, 0x52, 0x41, 0x44, 0x49, 0x4f, 0x10, 0x01, 0x12, 0x0e, 0x0a,
+     0x0a, 0x4c, 0x49, 0x44, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x53, 0x10,
+     0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x59, 0x53,
+     0x54, 0x45, 0x4d, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x49, 0x44,
+     0x5f, 0x43, 0x52, 0x41, 0x53, 0x48, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09,
+     0x4c, 0x49, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x53, 0x10, 0x05, 0x12,
+     0x10, 0x0a, 0x0c, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x45, 0x43, 0x55, 0x52,
+     0x49, 0x54, 0x59, 0x10, 0x06, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x49, 0x44,
+     0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x10, 0x07, 0x2a, 0x9b, 0x01,
+     0x0a, 0x12, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x4c, 0x6f, 0x67,
+     0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x10,
+     0x50, 0x52, 0x49, 0x4f, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49,
+     0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x52,
+     0x49, 0x4f, 0x5f, 0x55, 0x4e, 0x55, 0x53, 0x45, 0x44, 0x10, 0x01, 0x12,
+     0x10, 0x0a, 0x0c, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x56, 0x45, 0x52, 0x42,
+     0x4f, 0x53, 0x45, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x49,
+     0x4f, 0x5f, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x03, 0x12, 0x0d, 0x0a,
+     0x09, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x04,
+     0x12, 0x0d, 0x0a, 0x09, 0x50, 0x52, 0x49, 0x4f, 0x5f, 0x57, 0x41, 0x52,
+     0x4e, 0x10, 0x05, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x49, 0x4f, 0x5f,
+     0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x06, 0x12, 0x0e, 0x0a, 0x0a, 0x50,
+     0x52, 0x49, 0x4f, 0x5f, 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, 0x07, 0x2a,
+     0xbf, 0x06, 0x0a, 0x0f, 0x4d, 0x65, 0x6d, 0x69, 0x6e, 0x66, 0x6f, 0x43,
+     0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x17, 0x0a, 0x13, 0x4d,
+     0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45,
+     0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11,
+     0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x5f,
+     0x54, 0x4f, 0x54, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x4d,
+     0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x5f, 0x46,
+     0x52, 0x45, 0x45, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d,
+     0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x5f, 0x41, 0x56, 0x41,
+     0x49, 0x4c, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f,
+     0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x42, 0x55, 0x46, 0x46,
+     0x45, 0x52, 0x53, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x45, 0x4d,
+     0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x41, 0x43, 0x48, 0x45, 0x44, 0x10,
+     0x05, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f,
+     0x5f, 0x53, 0x57, 0x41, 0x50, 0x5f, 0x43, 0x41, 0x43, 0x48, 0x45, 0x44,
+     0x10, 0x06, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
+     0x4f, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x07, 0x12, 0x14,
+     0x0a, 0x10, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x49, 0x4e,
+     0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x08, 0x12, 0x17, 0x0a, 0x13,
+     0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x41, 0x43, 0x54, 0x49,
+     0x56, 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x09, 0x12, 0x19, 0x0a,
+     0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x49, 0x4e, 0x41,
+     0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x0a,
+     0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
      0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10,
-     0x0c, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f,
-     0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45,
-     0x10, 0x0d, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
-     0x4f, 0x5f, 0x4d, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x0e, 0x12,
-     0x16, 0x0a, 0x12, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53,
-     0x57, 0x41, 0x50, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c, 0x10, 0x0f, 0x12,
-     0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53,
-     0x57, 0x41, 0x50, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x10, 0x10, 0x12, 0x11,
-     0x0a, 0x0d, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x44, 0x49,
-     0x52, 0x54, 0x59, 0x10, 0x11, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d,
-     0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x42, 0x41,
-     0x43, 0x4b, 0x10, 0x12, 0x12, 0x16, 0x0a, 0x12, 0x4d, 0x45, 0x4d, 0x49,
-     0x4e, 0x46, 0x4f, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x5f, 0x50, 0x41, 0x47,
-     0x45, 0x53, 0x10, 0x13, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x45, 0x4d, 0x49,
-     0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x45, 0x44, 0x10, 0x14,
-     0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
-     0x53, 0x48, 0x4d, 0x45, 0x4d, 0x10, 0x15, 0x12, 0x10, 0x0a, 0x0c, 0x4d,
-     0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x10,
-     0x16, 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f,
-     0x5f, 0x53, 0x4c, 0x41, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49,
-     0x4d, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x17, 0x12, 0x1e, 0x0a, 0x1a, 0x4d,
-     0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x5f,
-     0x55, 0x4e, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c,
-     0x45, 0x10, 0x18, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
-     0x46, 0x4f, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x5f, 0x53, 0x54,
-     0x41, 0x43, 0x4b, 0x10, 0x19, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d,
-     0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x5f, 0x54, 0x41,
-     0x42, 0x4c, 0x45, 0x53, 0x10, 0x1a, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45,
-     0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54,
-     0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x10, 0x1b, 0x12, 0x17, 0x0a, 0x13,
-     0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4f, 0x4d, 0x4d,
-     0x49, 0x54, 0x45, 0x44, 0x5f, 0x41, 0x53, 0x10, 0x1c, 0x12, 0x19, 0x0a,
-     0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x56, 0x4d, 0x41,
-     0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c, 0x10, 0x1d,
-     0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
-     0x56, 0x4d, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x55, 0x53, 0x45, 0x44,
-     0x10, 0x1e, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
-     0x4f, 0x5f, 0x56, 0x4d, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x43, 0x48,
-     0x55, 0x4e, 0x4b, 0x10, 0x1f, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d,
-     0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4d, 0x41, 0x5f, 0x54, 0x4f, 0x54,
-     0x41, 0x4c, 0x10, 0x20, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x45, 0x4d, 0x49,
-     0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4d, 0x41, 0x5f, 0x46, 0x52, 0x45, 0x45,
-     0x10, 0x21, 0x2a, 0xc6, 0x15, 0x0a, 0x0e, 0x56, 0x6d, 0x73, 0x74, 0x61,
-     0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x16, 0x0a,
-     0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50,
-     0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a,
+     0x0b, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f,
+     0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x46, 0x49,
+     0x4c, 0x45, 0x10, 0x0c, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49,
+     0x4e, 0x46, 0x4f, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41,
+     0x42, 0x4c, 0x45, 0x10, 0x0d, 0x12, 0x13, 0x0a, 0x0f, 0x4d, 0x45, 0x4d,
+     0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44,
+     0x10, 0x0e, 0x12, 0x16, 0x0a, 0x12, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
+     0x4f, 0x5f, 0x53, 0x57, 0x41, 0x50, 0x5f, 0x54, 0x4f, 0x54, 0x41, 0x4c,
+     0x10, 0x0f, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46,
+     0x4f, 0x5f, 0x53, 0x57, 0x41, 0x50, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x10,
+     0x10, 0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f,
+     0x5f, 0x44, 0x49, 0x52, 0x54, 0x59, 0x10, 0x11, 0x12, 0x15, 0x0a, 0x11,
+     0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x57, 0x52, 0x49, 0x54,
+     0x45, 0x42, 0x41, 0x43, 0x4b, 0x10, 0x12, 0x12, 0x16, 0x0a, 0x12, 0x4d,
+     0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x5f,
+     0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x13, 0x12, 0x12, 0x0a, 0x0e, 0x4d,
+     0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x45,
+     0x44, 0x10, 0x14, 0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
+     0x46, 0x4f, 0x5f, 0x53, 0x48, 0x4d, 0x45, 0x4d, 0x10, 0x15, 0x12, 0x10,
+     0x0a, 0x0c, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x4c,
+     0x41, 0x42, 0x10, 0x16, 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x45, 0x4d, 0x49,
+     0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x5f, 0x52, 0x45, 0x43,
+     0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x17, 0x12, 0x1e,
+     0x0a, 0x1a, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x53, 0x4c,
+     0x41, 0x42, 0x5f, 0x55, 0x4e, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d,
+     0x41, 0x42, 0x4c, 0x45, 0x10, 0x18, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45,
+     0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c,
+     0x5f, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x10, 0x19, 0x12, 0x17, 0x0a, 0x13,
+     0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x50, 0x41, 0x47, 0x45,
+     0x5f, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, 0x1a, 0x12, 0x18, 0x0a,
+     0x14, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4f, 0x4d,
+     0x4d, 0x49, 0x54, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x10, 0x1b, 0x12,
+     0x17, 0x0a, 0x13, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43,
+     0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x45, 0x44, 0x5f, 0x41, 0x53, 0x10, 0x1c,
+     0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f,
+     0x56, 0x4d, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x54, 0x4f, 0x54, 0x41,
+     0x4c, 0x10, 0x1d, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x45, 0x4d, 0x49, 0x4e,
+     0x46, 0x4f, 0x5f, 0x56, 0x4d, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x55,
+     0x53, 0x45, 0x44, 0x10, 0x1e, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x45, 0x4d,
+     0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x56, 0x4d, 0x41, 0x4c, 0x4c, 0x4f, 0x43,
+     0x5f, 0x43, 0x48, 0x55, 0x4e, 0x4b, 0x10, 0x1f, 0x12, 0x15, 0x0a, 0x11,
+     0x4d, 0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4d, 0x41, 0x5f,
+     0x54, 0x4f, 0x54, 0x41, 0x4c, 0x10, 0x20, 0x12, 0x14, 0x0a, 0x10, 0x4d,
+     0x45, 0x4d, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x43, 0x4d, 0x41, 0x5f, 0x46,
+     0x52, 0x45, 0x45, 0x10, 0x21, 0x2a, 0xc6, 0x15, 0x0a, 0x0e, 0x56, 0x6d,
+     0x73, 0x74, 0x61, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73,
+     0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x55,
+     0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00,
+     0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
+     0x52, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53,
+     0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+     0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x42, 0x41,
+     0x54, 0x43, 0x48, 0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53,
+     0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54,
+     0x49, 0x56, 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x03, 0x12, 0x19,
+     0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
+     0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10,
+     0x04, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+     0x4e, 0x52, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f,
+     0x46, 0x49, 0x4c, 0x45, 0x10, 0x05, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x43, 0x54, 0x49,
+     0x56, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x06, 0x12, 0x19, 0x0a,
+     0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x55,
+     0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x07,
+     0x12, 0x13, 0x0a, 0x0f, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
+     0x52, 0x5f, 0x4d, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x08, 0x12, 0x18, 0x0a,
+     0x14, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41,
+     0x4e, 0x4f, 0x4e, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x09, 0x12,
+     0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52,
+     0x5f, 0x4d, 0x41, 0x50, 0x50, 0x45, 0x44, 0x10, 0x0a, 0x12, 0x18, 0x0a,
      0x14, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x46,
-     0x52, 0x45, 0x45, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x01, 0x12,
-     0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52,
-     0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x42, 0x41, 0x54, 0x43, 0x48,
-     0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
-     0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45,
-     0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x56,
-     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x43, 0x54,
-     0x49, 0x56, 0x45, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x1b,
-     0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
-     0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x46, 0x49, 0x4c,
-     0x45, 0x10, 0x05, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41,
-     0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x5f,
-     0x46, 0x49, 0x4c, 0x45, 0x10, 0x06, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d,
-     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x55, 0x4e, 0x45, 0x56,
-     0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x07, 0x12, 0x13, 0x0a,
-     0x0f, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x4d,
-     0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d,
-     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x4e, 0x4f, 0x4e,
-     0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x09, 0x12, 0x14, 0x0a, 0x10,
-     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x4d, 0x41,
-     0x50, 0x50, 0x45, 0x44, 0x10, 0x0a, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d,
-     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x46, 0x49, 0x4c, 0x45,
-     0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x0b, 0x12, 0x13, 0x0a, 0x0f,
-     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x44, 0x49,
-     0x52, 0x54, 0x59, 0x10, 0x0c, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53,
-     0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45,
-     0x42, 0x41, 0x43, 0x4b, 0x10, 0x0d, 0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d,
-     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x53, 0x4c, 0x41, 0x42,
-     0x5f, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c, 0x45,
-     0x10, 0x0e, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
-     0x5f, 0x4e, 0x52, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x5f, 0x55, 0x4e, 0x52,
-     0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x0f,
-     0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
-     0x52, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x5f, 0x54, 0x41, 0x42, 0x4c, 0x45,
-     0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x10, 0x12, 0x1a, 0x0a, 0x16,
-     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x4b, 0x45,
-     0x52, 0x4e, 0x45, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x10, 0x11,
-     0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
-     0x52, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x48, 0x45, 0x41, 0x44, 0x10, 0x12,
-     0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
-     0x52, 0x5f, 0x55, 0x4e, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x13,
-     0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
-     0x52, 0x5f, 0x42, 0x4f, 0x55, 0x4e, 0x43, 0x45, 0x10, 0x14, 0x12, 0x1a,
-     0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
-     0x56, 0x4d, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45,
-     0x10, 0x15, 0x12, 0x26, 0x0a, 0x22, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
-     0x5f, 0x4e, 0x52, 0x5f, 0x56, 0x4d, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x49,
-     0x4d, 0x4d, 0x45, 0x44, 0x49, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x45, 0x43,
-     0x4c, 0x41, 0x49, 0x4d, 0x10, 0x16, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d,
-     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x57, 0x52, 0x49, 0x54,
-     0x45, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x10, 0x17,
-     0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
-     0x52, 0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x41,
-     0x4e, 0x4f, 0x4e, 0x10, 0x18, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53,
-     0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41,
-     0x54, 0x45, 0x44, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x19, 0x12, 0x13,
-     0x0a, 0x0f, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
-     0x53, 0x48, 0x4d, 0x45, 0x4d, 0x10, 0x1a, 0x12, 0x15, 0x0a, 0x11, 0x56,
-     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x44, 0x49, 0x52,
-     0x54, 0x49, 0x45, 0x44, 0x10, 0x1b, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d,
-     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x57, 0x52, 0x49, 0x54,
-     0x54, 0x45, 0x4e, 0x10, 0x1c, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53,
-     0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53,
-     0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x1d, 0x12, 0x1d,
-     0x0a, 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x57, 0x4f, 0x52,
-     0x4b, 0x49, 0x4e, 0x47, 0x53, 0x45, 0x54, 0x5f, 0x52, 0x45, 0x46, 0x41,
-     0x55, 0x4c, 0x54, 0x10, 0x1e, 0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d, 0x53,
-     0x54, 0x41, 0x54, 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x49, 0x4e, 0x47, 0x53,
-     0x45, 0x54, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10,
-     0x1f, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
-     0x57, 0x4f, 0x52, 0x4b, 0x49, 0x4e, 0x47, 0x53, 0x45, 0x54, 0x5f, 0x4e,
-     0x4f, 0x44, 0x45, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x10, 0x20,
-     0x12, 0x28, 0x0a, 0x24, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e,
-     0x52, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53,
-     0x50, 0x41, 0x52, 0x45, 0x4e, 0x54, 0x5f, 0x48, 0x55, 0x47, 0x45, 0x50,
-     0x41, 0x47, 0x45, 0x53, 0x10, 0x21, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d,
-     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x46, 0x52, 0x45, 0x45,
-     0x5f, 0x43, 0x4d, 0x41, 0x10, 0x22, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d,
-     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x53, 0x57, 0x41, 0x50,
-     0x43, 0x41, 0x43, 0x48, 0x45, 0x10, 0x23, 0x12, 0x1d, 0x0a, 0x19, 0x56,
-     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x44, 0x49, 0x52,
-     0x54, 0x59, 0x5f, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44,
-     0x10, 0x24, 0x12, 0x28, 0x0a, 0x24, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
-     0x5f, 0x4e, 0x52, 0x5f, 0x44, 0x49, 0x52, 0x54, 0x59, 0x5f, 0x42, 0x41,
-     0x43, 0x4b, 0x47, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x54, 0x48, 0x52,
-     0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x10, 0x25, 0x12, 0x11, 0x0a, 0x0d,
-     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x50, 0x47, 0x49,
-     0x4e, 0x10, 0x26, 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x4d, 0x53, 0x54, 0x41,
-     0x54, 0x5f, 0x50, 0x47, 0x50, 0x47, 0x4f, 0x55, 0x54, 0x10, 0x27, 0x12,
-     0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47,
-     0x50, 0x47, 0x4f, 0x55, 0x54, 0x43, 0x4c, 0x45, 0x41, 0x4e, 0x10, 0x28,
-     0x12, 0x11, 0x0a, 0x0d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
-     0x53, 0x57, 0x50, 0x49, 0x4e, 0x10, 0x29, 0x12, 0x12, 0x0a, 0x0e, 0x56,
-     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x53, 0x57, 0x50, 0x4f, 0x55,
-     0x54, 0x10, 0x2a, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41,
-     0x54, 0x5f, 0x50, 0x47, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x44, 0x4d,
-     0x41, 0x10, 0x2b, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41,
-     0x54, 0x5f, 0x50, 0x47, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x5f, 0x4e, 0x4f,
-     0x52, 0x4d, 0x41, 0x4c, 0x10, 0x2c, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d,
+     0x49, 0x4c, 0x45, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x0b, 0x12,
+     0x13, 0x0a, 0x0f, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52,
+     0x5f, 0x44, 0x49, 0x52, 0x54, 0x59, 0x10, 0x0c, 0x12, 0x17, 0x0a, 0x13,
+     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x57, 0x52,
+     0x49, 0x54, 0x45, 0x42, 0x41, 0x43, 0x4b, 0x10, 0x0d, 0x12, 0x1e, 0x0a,
+     0x1a, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x53,
+     0x4c, 0x41, 0x42, 0x5f, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41,
+     0x42, 0x4c, 0x45, 0x10, 0x0e, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53,
+     0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x5f,
+     0x55, 0x4e, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x41, 0x42, 0x4c,
+     0x45, 0x10, 0x0f, 0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d, 0x53, 0x54, 0x41,
+     0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x5f, 0x54, 0x41,
+     0x42, 0x4c, 0x45, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x10, 0x12,
+     0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52,
+     0x5f, 0x4b, 0x45, 0x52, 0x4e, 0x45, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x43,
+     0x4b, 0x10, 0x11, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41,
+     0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x48, 0x45, 0x41,
+     0x44, 0x10, 0x12, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41,
+     0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x54, 0x41, 0x42, 0x4c,
+     0x45, 0x10, 0x13, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41,
+     0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x42, 0x4f, 0x55, 0x4e, 0x43, 0x45, 0x10,
+     0x14, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+     0x4e, 0x52, 0x5f, 0x56, 0x4d, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x57, 0x52,
+     0x49, 0x54, 0x45, 0x10, 0x15, 0x12, 0x26, 0x0a, 0x22, 0x56, 0x4d, 0x53,
+     0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x56, 0x4d, 0x53, 0x43, 0x41,
+     0x4e, 0x5f, 0x49, 0x4d, 0x4d, 0x45, 0x44, 0x49, 0x41, 0x54, 0x45, 0x5f,
+     0x52, 0x45, 0x43, 0x4c, 0x41, 0x49, 0x4d, 0x10, 0x16, 0x12, 0x1c, 0x0a,
+     0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x57,
+     0x52, 0x49, 0x54, 0x45, 0x42, 0x41, 0x43, 0x4b, 0x5f, 0x54, 0x45, 0x4d,
+     0x50, 0x10, 0x17, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53, 0x54, 0x41,
+     0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45,
+     0x44, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x10, 0x18, 0x12, 0x1b, 0x0a, 0x17,
+     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x53,
+     0x4f, 0x4c, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10,
+     0x19, 0x12, 0x13, 0x0a, 0x0f, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+     0x4e, 0x52, 0x5f, 0x53, 0x48, 0x4d, 0x45, 0x4d, 0x10, 0x1a, 0x12, 0x15,
+     0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
+     0x44, 0x49, 0x52, 0x54, 0x49, 0x45, 0x44, 0x10, 0x1b, 0x12, 0x15, 0x0a,
+     0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x57,
+     0x52, 0x49, 0x54, 0x54, 0x45, 0x4e, 0x10, 0x1c, 0x12, 0x1b, 0x0a, 0x17,
+     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x50, 0x41,
+     0x47, 0x45, 0x53, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10,
+     0x1d, 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+     0x57, 0x4f, 0x52, 0x4b, 0x49, 0x4e, 0x47, 0x53, 0x45, 0x54, 0x5f, 0x52,
+     0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x1e, 0x12, 0x1e, 0x0a, 0x1a,
+     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x49,
+     0x4e, 0x47, 0x53, 0x45, 0x54, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x41,
+     0x54, 0x45, 0x10, 0x1f, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54,
+     0x41, 0x54, 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x49, 0x4e, 0x47, 0x53, 0x45,
+     0x54, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x52, 0x45, 0x43, 0x4c, 0x41, 0x49,
+     0x4d, 0x10, 0x20, 0x12, 0x28, 0x0a, 0x24, 0x56, 0x4d, 0x53, 0x54, 0x41,
+     0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x41, 0x4e, 0x4f, 0x4e, 0x5f, 0x54, 0x52,
+     0x41, 0x4e, 0x53, 0x50, 0x41, 0x52, 0x45, 0x4e, 0x54, 0x5f, 0x48, 0x55,
+     0x47, 0x45, 0x50, 0x41, 0x47, 0x45, 0x53, 0x10, 0x21, 0x12, 0x16, 0x0a,
+     0x12, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x46,
+     0x52, 0x45, 0x45, 0x5f, 0x43, 0x4d, 0x41, 0x10, 0x22, 0x12, 0x17, 0x0a,
+     0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x53,
+     0x57, 0x41, 0x50, 0x43, 0x41, 0x43, 0x48, 0x45, 0x10, 0x23, 0x12, 0x1d,
+     0x0a, 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f,
+     0x44, 0x49, 0x52, 0x54, 0x59, 0x5f, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48,
+     0x4f, 0x4c, 0x44, 0x10, 0x24, 0x12, 0x28, 0x0a, 0x24, 0x56, 0x4d, 0x53,
+     0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x44, 0x49, 0x52, 0x54, 0x59,
+     0x5f, 0x42, 0x41, 0x43, 0x4b, 0x47, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f,
+     0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x10, 0x25, 0x12,
+     0x11, 0x0a, 0x0d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47,
+     0x50, 0x47, 0x49, 0x4e, 0x10, 0x26, 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x50, 0x47, 0x4f, 0x55, 0x54,
+     0x10, 0x27, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+     0x5f, 0x50, 0x47, 0x50, 0x47, 0x4f, 0x55, 0x54, 0x43, 0x4c, 0x45, 0x41,
+     0x4e, 0x10, 0x28, 0x12, 0x11, 0x0a, 0x0d, 0x56, 0x4d, 0x53, 0x54, 0x41,
+     0x54, 0x5f, 0x50, 0x53, 0x57, 0x50, 0x49, 0x4e, 0x10, 0x29, 0x12, 0x12,
+     0x0a, 0x0e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x53, 0x57,
+     0x50, 0x4f, 0x55, 0x54, 0x10, 0x2a, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d,
      0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x41, 0x4c, 0x4c, 0x4f, 0x43,
-     0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x2d, 0x12, 0x11,
-     0x0a, 0x0d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x46,
-     0x52, 0x45, 0x45, 0x10, 0x2e, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53,
-     0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x41, 0x43, 0x54, 0x49, 0x56, 0x41,
-     0x54, 0x45, 0x10, 0x2f, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54,
-     0x41, 0x54, 0x5f, 0x50, 0x47, 0x44, 0x45, 0x41, 0x43, 0x54, 0x49, 0x56,
-     0x41, 0x54, 0x45, 0x10, 0x30, 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x4d, 0x53,
-     0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10,
-     0x31, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
-     0x50, 0x47, 0x4d, 0x41, 0x4a, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x32,
-     0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
-     0x47, 0x52, 0x45, 0x46, 0x49, 0x4c, 0x4c, 0x5f, 0x44, 0x4d, 0x41, 0x10,
-     0x33, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
-     0x50, 0x47, 0x52, 0x45, 0x46, 0x49, 0x4c, 0x4c, 0x5f, 0x4e, 0x4f, 0x52,
-     0x4d, 0x41, 0x4c, 0x10, 0x34, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d, 0x53,
-     0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x52, 0x45, 0x46, 0x49, 0x4c, 0x4c,
-     0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x35, 0x12, 0x1d,
-     0x0a, 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53,
-     0x54, 0x45, 0x41, 0x4c, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f,
-     0x44, 0x4d, 0x41, 0x10, 0x36, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53,
+     0x5f, 0x44, 0x4d, 0x41, 0x10, 0x2b, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x41, 0x4c, 0x4c, 0x4f, 0x43,
+     0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x2c, 0x12, 0x1a, 0x0a,
+     0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x41, 0x4c,
+     0x4c, 0x4f, 0x43, 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10,
+     0x2d, 0x12, 0x11, 0x0a, 0x0d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+     0x50, 0x47, 0x46, 0x52, 0x45, 0x45, 0x10, 0x2e, 0x12, 0x15, 0x0a, 0x11,
+     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x41, 0x43, 0x54,
+     0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x2f, 0x12, 0x17, 0x0a, 0x13, 0x56,
+     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x44, 0x45, 0x41, 0x43,
+     0x54, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x30, 0x12, 0x12, 0x0a, 0x0e,
+     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x46, 0x41, 0x55,
+     0x4c, 0x54, 0x10, 0x31, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54,
+     0x41, 0x54, 0x5f, 0x50, 0x47, 0x4d, 0x41, 0x4a, 0x46, 0x41, 0x55, 0x4c,
+     0x54, 0x10, 0x32, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41,
+     0x54, 0x5f, 0x50, 0x47, 0x52, 0x45, 0x46, 0x49, 0x4c, 0x4c, 0x5f, 0x44,
+     0x4d, 0x41, 0x10, 0x33, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54,
+     0x41, 0x54, 0x5f, 0x50, 0x47, 0x52, 0x45, 0x46, 0x49, 0x4c, 0x4c, 0x5f,
+     0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x34, 0x12, 0x1b, 0x0a, 0x17,
+     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x52, 0x45, 0x46,
+     0x49, 0x4c, 0x4c, 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10,
+     0x35, 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+     0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x4b, 0x53, 0x57, 0x41,
+     0x50, 0x44, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x36, 0x12, 0x20, 0x0a, 0x1c,
+     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45,
+     0x41, 0x4c, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4e, 0x4f,
+     0x52, 0x4d, 0x41, 0x4c, 0x10, 0x37, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c,
+     0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4d, 0x4f, 0x56, 0x41,
+     0x42, 0x4c, 0x45, 0x10, 0x38, 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x4d, 0x53,
      0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f,
-     0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41,
-     0x4c, 0x10, 0x37, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41,
-     0x54, 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x4b, 0x53,
-     0x57, 0x41, 0x50, 0x44, 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45,
-     0x10, 0x38, 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
-     0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x44, 0x49, 0x52,
-     0x45, 0x43, 0x54, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x39, 0x12, 0x20, 0x0a,
-     0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54,
-     0x45, 0x41, 0x4c, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x4e,
-     0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x3a, 0x12, 0x21, 0x0a, 0x1d, 0x56,
-     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x54, 0x45, 0x41,
-     0x4c, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x4f, 0x56,
-     0x41, 0x42, 0x4c, 0x45, 0x10, 0x3b, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d,
-     0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f,
-     0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x3c,
-     0x12, 0x1f, 0x0a, 0x1b, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
+     0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x44, 0x4d, 0x41, 0x10, 0x39,
+     0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
+     0x47, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43,
+     0x54, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x3a, 0x12, 0x21,
+     0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53,
+     0x54, 0x45, 0x41, 0x4c, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f,
+     0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x3b, 0x12, 0x1c, 0x0a,
+     0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43,
+     0x41, 0x4e, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x44, 0x4d,
+     0x41, 0x10, 0x3c, 0x12, 0x1f, 0x0a, 0x1b, 0x56, 0x4d, 0x53, 0x54, 0x41,
+     0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x4b, 0x53, 0x57,
+     0x41, 0x50, 0x44, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x3d,
+     0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
      0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44,
-     0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x3d, 0x12, 0x20, 0x0a,
-     0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43,
-     0x41, 0x4e, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4d, 0x4f,
-     0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x3e, 0x12, 0x1c, 0x0a, 0x18, 0x56,
-     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e,
-     0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x44, 0x4d, 0x41, 0x10,
-     0x3f, 0x12, 0x1f, 0x0a, 0x1b, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+     0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x3e, 0x12, 0x1c,
+     0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53,
+     0x43, 0x41, 0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x44,
+     0x4d, 0x41, 0x10, 0x3f, 0x12, 0x1f, 0x0a, 0x1b, 0x56, 0x4d, 0x53, 0x54,
+     0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x44, 0x49,
+     0x52, 0x45, 0x43, 0x54, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10,
+     0x40, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
      0x50, 0x47, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43,
-     0x54, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x40, 0x12, 0x20,
-     0x0a, 0x1c, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53,
-     0x43, 0x41, 0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x4d,
-     0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x41, 0x12, 0x21, 0x0a, 0x1d,
-     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x53, 0x43, 0x41,
-     0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x54, 0x48, 0x52,
-     0x4f, 0x54, 0x54, 0x4c, 0x45, 0x10, 0x42, 0x12, 0x17, 0x0a, 0x13, 0x56,
-     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x49, 0x4e, 0x4f, 0x44,
-     0x45, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x10, 0x43, 0x12, 0x18, 0x0a, 0x14,
-     0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x53,
-     0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x44, 0x12, 0x1c,
-     0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4b, 0x53, 0x57,
-     0x41, 0x50, 0x44, 0x5f, 0x49, 0x4e, 0x4f, 0x44, 0x45, 0x53, 0x54, 0x45,
-     0x41, 0x4c, 0x10, 0x45, 0x12, 0x27, 0x0a, 0x23, 0x56, 0x4d, 0x53, 0x54,
-     0x41, 0x54, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x4c, 0x4f,
-     0x57, 0x5f, 0x57, 0x4d, 0x41, 0x52, 0x4b, 0x5f, 0x48, 0x49, 0x54, 0x5f,
-     0x51, 0x55, 0x49, 0x43, 0x4b, 0x4c, 0x59, 0x10, 0x46, 0x12, 0x28, 0x0a,
-     0x24, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4b, 0x53, 0x57, 0x41,
-     0x50, 0x44, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x5f, 0x57, 0x4d, 0x41, 0x52,
-     0x4b, 0x5f, 0x48, 0x49, 0x54, 0x5f, 0x51, 0x55, 0x49, 0x43, 0x4b, 0x4c,
-     0x59, 0x10, 0x47, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41,
-     0x54, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x4f, 0x55, 0x54, 0x52, 0x55, 0x4e,
-     0x10, 0x48, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
-     0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x10,
-     0x49, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
-     0x50, 0x47, 0x52, 0x4f, 0x54, 0x41, 0x54, 0x45, 0x44, 0x10, 0x4a, 0x12,
-     0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x44, 0x52,
-     0x4f, 0x50, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x43, 0x41, 0x43, 0x48, 0x45,
-     0x10, 0x4b, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
-     0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x53, 0x4c, 0x41, 0x42, 0x10, 0x4c,
-     0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50,
-     0x47, 0x4d, 0x49, 0x47, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x55, 0x43,
-     0x43, 0x45, 0x53, 0x53, 0x10, 0x4d, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d,
-     0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x4d, 0x49, 0x47, 0x52, 0x41,
-     0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x10, 0x4e, 0x12, 0x22, 0x0a,
-     0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50,
-     0x41, 0x43, 0x54, 0x5f, 0x4d, 0x49, 0x47, 0x52, 0x41, 0x54, 0x45, 0x5f,
-     0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x4f, 0x12, 0x1f, 0x0a,
-     0x1b, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50,
-     0x41, 0x43, 0x54, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x5f, 0x53, 0x43, 0x41,
-     0x4e, 0x4e, 0x45, 0x44, 0x10, 0x50, 0x12, 0x1b, 0x0a, 0x17, 0x56, 0x4d,
-     0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54,
-     0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45, 0x44, 0x10, 0x51, 0x12,
-     0x18, 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f,
-     0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x10,
-     0x52, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
-     0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x46, 0x41, 0x49, 0x4c,
-     0x10, 0x53, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
-     0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x53, 0x55, 0x43,
-     0x43, 0x45, 0x53, 0x53, 0x10, 0x54, 0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x4d,
-     0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54,
-     0x5f, 0x44, 0x41, 0x45, 0x4d, 0x4f, 0x4e, 0x5f, 0x57, 0x41, 0x4b, 0x45,
-     0x10, 0x55, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
-     0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45,
-     0x5f, 0x50, 0x47, 0x53, 0x5f, 0x43, 0x55, 0x4c, 0x4c, 0x45, 0x44, 0x10,
-     0x56, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
-     0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f,
-     0x50, 0x47, 0x53, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10,
-     0x57, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
-     0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f,
-     0x50, 0x47, 0x53, 0x5f, 0x52, 0x45, 0x53, 0x43, 0x55, 0x45, 0x44, 0x10,
-     0x58, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
-     0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f,
-     0x50, 0x47, 0x53, 0x5f, 0x4d, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10,
-     0x59, 0x12, 0x24, 0x0a, 0x20, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
-     0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f,
-     0x50, 0x47, 0x53, 0x5f, 0x4d, 0x55, 0x4e, 0x4c, 0x4f, 0x43, 0x4b, 0x45,
-     0x44, 0x10, 0x5a, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41,
-     0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c,
-     0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x43, 0x4c, 0x45, 0x41, 0x52, 0x45,
-     0x44, 0x10, 0x5b, 0x12, 0x23, 0x0a, 0x1f, 0x56, 0x4d, 0x53, 0x54, 0x41,
-     0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42, 0x4c,
-     0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x53, 0x54, 0x52, 0x41, 0x4e, 0x44,
-     0x45, 0x44, 0x10, 0x5c, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53, 0x54,
-     0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x5a, 0x53, 0x50, 0x41, 0x47, 0x45,
-     0x53, 0x10, 0x5d, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41,
-     0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x4f, 0x4e, 0x5f, 0x48, 0x45, 0x41,
-     0x50, 0x10, 0x5e, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d, 0x53, 0x54, 0x41,
-     0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x47, 0x50, 0x55, 0x5f, 0x48, 0x45, 0x41,
-     0x50, 0x10, 0x5f}};
+     0x54, 0x5f, 0x4d, 0x4f, 0x56, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x41, 0x12,
+     0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47,
+     0x53, 0x43, 0x41, 0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x5f,
+     0x54, 0x48, 0x52, 0x4f, 0x54, 0x54, 0x4c, 0x45, 0x10, 0x42, 0x12, 0x17,
+     0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x49,
+     0x4e, 0x4f, 0x44, 0x45, 0x53, 0x54, 0x45, 0x41, 0x4c, 0x10, 0x43, 0x12,
+     0x18, 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x53, 0x4c,
+     0x41, 0x42, 0x53, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10,
+     0x44, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f,
+     0x4b, 0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x49, 0x4e, 0x4f, 0x44, 0x45,
+     0x53, 0x54, 0x45, 0x41, 0x4c, 0x10, 0x45, 0x12, 0x27, 0x0a, 0x23, 0x56,
+     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4b, 0x53, 0x57, 0x41, 0x50, 0x44,
+     0x5f, 0x4c, 0x4f, 0x57, 0x5f, 0x57, 0x4d, 0x41, 0x52, 0x4b, 0x5f, 0x48,
+     0x49, 0x54, 0x5f, 0x51, 0x55, 0x49, 0x43, 0x4b, 0x4c, 0x59, 0x10, 0x46,
+     0x12, 0x28, 0x0a, 0x24, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4b,
+     0x53, 0x57, 0x41, 0x50, 0x44, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x5f, 0x57,
+     0x4d, 0x41, 0x52, 0x4b, 0x5f, 0x48, 0x49, 0x54, 0x5f, 0x51, 0x55, 0x49,
+     0x43, 0x4b, 0x4c, 0x59, 0x10, 0x47, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x4f, 0x55, 0x54,
+     0x52, 0x55, 0x4e, 0x10, 0x48, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x4d, 0x53,
+     0x54, 0x41, 0x54, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x53, 0x54, 0x41,
+     0x4c, 0x4c, 0x10, 0x49, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53, 0x54,
+     0x41, 0x54, 0x5f, 0x50, 0x47, 0x52, 0x4f, 0x54, 0x41, 0x54, 0x45, 0x44,
+     0x10, 0x4a, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+     0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x43, 0x41,
+     0x43, 0x48, 0x45, 0x10, 0x4b, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x4d, 0x53,
+     0x54, 0x41, 0x54, 0x5f, 0x44, 0x52, 0x4f, 0x50, 0x5f, 0x53, 0x4c, 0x41,
+     0x42, 0x10, 0x4c, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x4d, 0x53, 0x54, 0x41,
+     0x54, 0x5f, 0x50, 0x47, 0x4d, 0x49, 0x47, 0x52, 0x41, 0x54, 0x45, 0x5f,
+     0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x4d, 0x12, 0x19, 0x0a,
+     0x15, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x50, 0x47, 0x4d, 0x49,
+     0x47, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x10, 0x4e,
+     0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43,
+     0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x4d, 0x49, 0x47, 0x52, 0x41,
+     0x54, 0x45, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x4f,
+     0x12, 0x1f, 0x0a, 0x1b, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43,
+     0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x5f,
+     0x53, 0x43, 0x41, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x50, 0x12, 0x1b, 0x0a,
+     0x17, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50,
+     0x41, 0x43, 0x54, 0x5f, 0x49, 0x53, 0x4f, 0x4c, 0x41, 0x54, 0x45, 0x44,
+     0x10, 0x51, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54,
+     0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x53, 0x54, 0x41,
+     0x4c, 0x4c, 0x10, 0x52, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4d, 0x53, 0x54,
+     0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x46,
+     0x41, 0x49, 0x4c, 0x10, 0x53, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x4d, 0x53,
+     0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f,
+     0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x54, 0x12, 0x1e, 0x0a,
+     0x1a, 0x56, 0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50,
+     0x41, 0x43, 0x54, 0x5f, 0x44, 0x41, 0x45, 0x4d, 0x4f, 0x4e, 0x5f, 0x57,
+     0x41, 0x4b, 0x45, 0x10, 0x55, 0x12, 0x21, 0x0a, 0x1d, 0x56, 0x4d, 0x53,
+     0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41,
+     0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x43, 0x55, 0x4c, 0x4c,
+     0x45, 0x44, 0x10, 0x56, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54,
+     0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42,
+     0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x4e,
+     0x45, 0x44, 0x10, 0x57, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54,
+     0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42,
+     0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x52, 0x45, 0x53, 0x43, 0x55,
+     0x45, 0x44, 0x10, 0x58, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d, 0x53, 0x54,
+     0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42,
+     0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x4d, 0x4c, 0x4f, 0x43, 0x4b,
+     0x45, 0x44, 0x10, 0x59, 0x12, 0x24, 0x0a, 0x20, 0x56, 0x4d, 0x53, 0x54,
+     0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54, 0x41, 0x42,
+     0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x4d, 0x55, 0x4e, 0x4c, 0x4f,
+     0x43, 0x4b, 0x45, 0x44, 0x10, 0x5a, 0x12, 0x22, 0x0a, 0x1e, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54,
+     0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x43, 0x4c, 0x45,
+     0x41, 0x52, 0x45, 0x44, 0x10, 0x5b, 0x12, 0x23, 0x0a, 0x1f, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x45, 0x56, 0x49, 0x43, 0x54,
+     0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x47, 0x53, 0x5f, 0x53, 0x54, 0x52,
+     0x41, 0x4e, 0x44, 0x45, 0x44, 0x10, 0x5c, 0x12, 0x15, 0x0a, 0x11, 0x56,
+     0x4d, 0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x5a, 0x53, 0x50,
+     0x41, 0x47, 0x45, 0x53, 0x10, 0x5d, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x49, 0x4f, 0x4e, 0x5f,
+     0x48, 0x45, 0x41, 0x50, 0x10, 0x5e, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x4d,
+     0x53, 0x54, 0x41, 0x54, 0x5f, 0x4e, 0x52, 0x5f, 0x47, 0x50, 0x55, 0x5f,
+     0x48, 0x45, 0x41, 0x50, 0x10, 0x5f}};
 
 }  // namespace perfetto
 
diff --git a/src/protozero/scattered_heap_buffer.cc b/src/protozero/scattered_heap_buffer.cc
index eb6883e..682a059 100644
--- a/src/protozero/scattered_heap_buffer.cc
+++ b/src/protozero/scattered_heap_buffer.cc
@@ -56,11 +56,9 @@
 std::vector<uint8_t> ScatteredHeapBuffer::StitchSlices() {
   AdjustUsedSizeOfCurrentSlice();
   std::vector<uint8_t> buffer;
-  size_t i = 0;
   for (const auto& slice : slices_) {
     auto used_range = slice.GetUsedRange();
     buffer.insert(buffer.end(), used_range.begin, used_range.end);
-    i++;
   }
   return buffer;
 }
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index 75a9be1..528c10e 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -83,8 +83,8 @@
     "fuchsia_trace_tokenizer.h",
     "fuchsia_trace_utils.cc",
     "fuchsia_trace_utils.h",
-    "graphics_frame_event_parser.cc",
-    "graphics_frame_event_parser.h",
+    "graphics_event_parser.cc",
+    "graphics_event_parser.h",
     "gzip_trace_parser.cc",
     "gzip_trace_parser.h",
     "heap_profile_allocation_table.cc",
diff --git a/src/trace_processor/db/BUILD.gn b/src/trace_processor/db/BUILD.gn
index c25fef1..b09dc86 100644
--- a/src/trace_processor/db/BUILD.gn
+++ b/src/trace_processor/db/BUILD.gn
@@ -49,3 +49,17 @@
     "../../../gn:gtest_and_gmock",
   ]
 }
+
+if (enable_perfetto_benchmarks) {
+  source_set("benchmarks") {
+    testonly = true
+    deps = [
+      ":lib",
+      "../../../gn:benchmark",
+      "../../../gn:default_deps",
+    ]
+    sources = [
+      "bit_vector_benchmark.cc",
+    ]
+  }
+}
diff --git a/src/trace_processor/db/bit_vector_benchmark.cc b/src/trace_processor/db/bit_vector_benchmark.cc
new file mode 100644
index 0000000..d6ed930
--- /dev/null
+++ b/src/trace_processor/db/bit_vector_benchmark.cc
@@ -0,0 +1,117 @@
+// 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.
+
+#include <random>
+
+#include <benchmark/benchmark.h>
+
+#include "src/trace_processor/db/bit_vector.h"
+
+static void BM_BitVectorAppend(benchmark::State& state) {
+  static constexpr uint32_t kPoolSize = 1024 * 1024;
+  std::vector<bool> bit_pool(kPoolSize);
+
+  static constexpr uint32_t kRandomSeed = 42;
+  std::minstd_rand0 rnd_engine(kRandomSeed);
+  for (uint32_t i = 0; i < kPoolSize; ++i) {
+    bit_pool[i] = rnd_engine() % 2;
+  }
+
+  perfetto::trace_processor::BitVector bv;
+  uint32_t pool_idx = 0;
+  for (auto _ : state) {
+    bv.Append(bit_pool[pool_idx]);
+    pool_idx = (pool_idx + 1) % kPoolSize;
+    benchmark::ClobberMemory();
+  }
+}
+BENCHMARK(BM_BitVectorAppend);
+
+static void BM_BitVectorSet(benchmark::State& state) {
+  static constexpr uint32_t kPoolSize = 1024 * 1024;
+  std::vector<bool> bit_pool(kPoolSize);
+  std::vector<uint32_t> row_pool(kPoolSize);
+
+  static constexpr uint32_t kSize = 123456;
+  perfetto::trace_processor::BitVector bv;
+
+  static constexpr uint32_t kRandomSeed = 42;
+  std::minstd_rand0 rnd_engine(kRandomSeed);
+  for (uint32_t i = 0; i < kPoolSize; ++i) {
+    bit_pool[i] = rnd_engine() % 2;
+    row_pool[i] = rnd_engine() % kSize;
+  }
+
+  for (uint32_t i = 0; i < kSize; ++i) {
+    bv.Append(rnd_engine() % 2);
+  }
+
+  uint32_t pool_idx = 0;
+  for (auto _ : state) {
+    bv.Set(row_pool[pool_idx], bit_pool[pool_idx]);
+    pool_idx = (pool_idx + 1) % kPoolSize;
+    benchmark::ClobberMemory();
+  }
+}
+BENCHMARK(BM_BitVectorSet);
+
+static void BM_BitVectorIndexOfNthSet(benchmark::State& state) {
+  static constexpr uint32_t kPoolSize = 1024 * 1024;
+  std::vector<uint32_t> row_pool(kPoolSize);
+
+  static constexpr uint32_t kSize = 123456;
+  perfetto::trace_processor::BitVector bv;
+
+  static constexpr uint32_t kRandomSeed = 42;
+  std::minstd_rand0 rnd_engine(kRandomSeed);
+  for (uint32_t i = 0; i < kSize; ++i) {
+    bool value = rnd_engine() % 2;
+    bv.Append(value);
+  }
+
+  uint32_t set_bit_count = bv.GetNumBitsSet();
+  for (uint32_t i = 0; i < kPoolSize; ++i) {
+    row_pool[i] = rnd_engine() % set_bit_count;
+  }
+
+  uint32_t pool_idx = 0;
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(bv.IndexOfNthSet(row_pool[pool_idx]));
+    pool_idx = (pool_idx + 1) % kPoolSize;
+  }
+}
+BENCHMARK(BM_BitVectorIndexOfNthSet);
+
+static void BM_BitVectorGetNumBitsSet(benchmark::State& state) {
+  static constexpr uint32_t kSize = 123456;
+  perfetto::trace_processor::BitVector bv;
+  uint32_t count = 0;
+
+  static constexpr uint32_t kRandomSeed = 42;
+  std::minstd_rand0 rnd_engine(kRandomSeed);
+  for (uint32_t i = 0; i < kSize; ++i) {
+    bool value = rnd_engine() % 2;
+    bv.Append(value);
+
+    if (value)
+      count++;
+  }
+
+  uint32_t res = count;
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(res &= bv.GetNumBitsSet());
+  }
+  PERFETTO_CHECK(res == count);
+}
+BENCHMARK(BM_BitVectorGetNumBitsSet);
diff --git a/src/trace_processor/graphics_event_parser.cc b/src/trace_processor/graphics_event_parser.cc
new file mode 100644
index 0000000..fdf1cd5
--- /dev/null
+++ b/src/trace_processor/graphics_event_parser.cc
@@ -0,0 +1,287 @@
+/*
+ * 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.
+ */
+
+#include "src/trace_processor/graphics_event_parser.h"
+
+#include "perfetto/protozero/field.h"
+#include "src/trace_processor/args_tracker.h"
+#include "src/trace_processor/event_tracker.h"
+#include "src/trace_processor/slice_tracker.h"
+#include "src/trace_processor/trace_processor_context.h"
+#include "src/trace_processor/virtual_track_tracker.h"
+
+#include "protos/perfetto/common/gpu_counter_descriptor.pbzero.h"
+#include "protos/perfetto/trace/android/graphics_frame_event.pbzero.h"
+#include "protos/perfetto/trace/gpu/gpu_counter_event.pbzero.h"
+#include "protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+GraphicsEventParser::~GraphicsEventParser() = default;
+
+GraphicsEventParser::GraphicsEventParser(TraceProcessorContext* context)
+    : context_(context),
+      graphics_event_scope_id_(
+          context->storage->InternString("graphics_frame_event")),
+      unknown_event_name_id_(context->storage->InternString("unknown_event")),
+      no_layer_name_name_id_(context->storage->InternString("no_layer_name")),
+      layer_name_key_id_(context->storage->InternString("layer_name")),
+      event_type_name_ids_{
+          {context->storage->InternString("unspecified_event") /* UNSPECIFIED */,
+           context->storage->InternString("Dequeue") /* DEQUEUE */,
+           context->storage->InternString("Queue") /* QUEUE */,
+           context->storage->InternString("Post") /* POST */,
+           context->storage->InternString("AcquireFenceSignaled") /* ACQUIRE_FENCE */,
+           context->storage->InternString("Latch") /* LATCH */,
+           context->storage->InternString("HWCCompositionQueued") /* HWC_COMPOSITION_QUEUED */,
+           context->storage->InternString("FallbackComposition") /* FALLBACK_COMPOSITION */,
+           context->storage->InternString("PresentFenceSignaled") /* PRESENT_FENCE */,
+           context->storage->InternString("ReleaseFenceSignaled") /* RELEASE_FENCE */,
+           context->storage->InternString("Modify") /* MODIFY */}} {}
+
+void GraphicsEventParser::ParseGpuCounterEvent(int64_t ts, ConstBytes blob) {
+  protos::pbzero::GpuCounterEvent::Decoder event(blob.data, blob.size);
+
+  protos::pbzero::GpuCounterDescriptor::Decoder descriptor(
+      event.counter_descriptor());
+  // Add counter spec to ID map.
+  for (auto it = descriptor.specs(); it; ++it) {
+    protos::pbzero::GpuCounterDescriptor_GpuCounterSpec::Decoder spec(
+        it->data(), it->size());
+    if (!spec.has_counter_id()) {
+      PERFETTO_ELOG("Counter spec missing counter id");
+      context_->storage->IncrementStats(stats::gpu_counters_invalid_spec);
+      continue;
+    }
+    if (!spec.has_name()) {
+      context_->storage->IncrementStats(stats::gpu_counters_invalid_spec);
+      continue;
+    }
+
+    auto counter_id = spec.counter_id();
+    auto name = spec.name();
+    if (gpu_counter_ids_.find(counter_id) == gpu_counter_ids_.end()) {
+      auto desc = spec.description();
+
+      StringId unit_id = 0;
+      if (spec.has_numerator_units() || spec.has_denominator_units()) {
+        char buffer[1024];
+        base::StringWriter unit(buffer, sizeof(buffer));
+        for (auto numer = spec.numerator_units(); numer; ++numer) {
+          if (unit.pos()) {
+            unit.AppendChar(':');
+          }
+          unit.AppendInt(numer->as_int64());
+        }
+        char sep = '/';
+        for (auto denom = spec.denominator_units(); denom; ++denom) {
+          unit.AppendChar(sep);
+          unit.AppendInt(denom->as_int64());
+          sep = ':';
+        }
+        unit_id = context_->storage->InternString(unit.GetStringView());
+      }
+
+      auto name_id = context_->storage->InternString(name);
+      auto desc_id = context_->storage->InternString(desc);
+      auto* definitions = context_->storage->mutable_counter_definitions();
+      auto defn_id = definitions->AddCounterDefinition(
+          name_id, 0, RefType::kRefGpuId, desc_id, unit_id);
+      gpu_counter_ids_.emplace(counter_id, defn_id);
+    } else {
+      // Either counter spec was repeated or it came after counter data.
+      PERFETTO_ELOG("Duplicated counter spec found. (counter_id=%d, name=%s)",
+                    counter_id, name.ToStdString().c_str());
+      context_->storage->IncrementStats(stats::gpu_counters_invalid_spec);
+    }
+  }
+
+  for (auto it = event.counters(); it; ++it) {
+    protos::pbzero::GpuCounterEvent_GpuCounter::Decoder counter(it->data(),
+                                                                it->size());
+    if (counter.has_counter_id() &&
+        (counter.has_int_value() || counter.has_double_value())) {
+      auto counter_id = counter.counter_id();
+      // Check missing counter_id
+      if (gpu_counter_ids_.find(counter_id) == gpu_counter_ids_.end()) {
+        char buffer[64];
+        base::StringWriter writer(buffer, sizeof(buffer));
+        writer.AppendString("gpu_counter(");
+        writer.AppendUnsignedInt(counter_id);
+        writer.AppendString(")");
+        auto name_id = context_->storage->InternString(writer.GetStringView());
+        auto* definitions = context_->storage->mutable_counter_definitions();
+        auto defn_id =
+            definitions->AddCounterDefinition(name_id, 0, RefType::kRefGpuId);
+        gpu_counter_ids_.emplace(counter_id, defn_id);
+        context_->storage->IncrementStats(stats::gpu_counters_missing_spec);
+      }
+      if (counter.has_int_value()) {
+        context_->event_tracker->PushCounter(ts, counter.int_value(),
+                                             gpu_counter_ids_[counter_id]);
+      } else {
+        context_->event_tracker->PushCounter(ts, counter.double_value(),
+                                             gpu_counter_ids_[counter_id]);
+      }
+    }
+  }
+}
+
+void GraphicsEventParser::ParseGpuRenderStageEvent(int64_t ts,
+                                                   ConstBytes blob) {
+  protos::pbzero::GpuRenderStageEvent::Decoder event(blob.data, blob.size);
+
+  if (event.has_specifications()) {
+    protos::pbzero::GpuRenderStageEvent_Specifications::Decoder spec(
+        event.specifications().data, event.specifications().size);
+    for (auto it = spec.hw_queue(); it; ++it) {
+      protos::pbzero::GpuRenderStageEvent_Specifications_Description::Decoder
+          hw_queue(it->data(), it->size());
+      if (hw_queue.has_name()) {
+        // TODO: create vtrack for each HW queue when it's ready.
+        gpu_hw_queue_ids_.emplace_back(
+            context_->storage->InternString(hw_queue.name()));
+      }
+    }
+    for (auto it = spec.stage(); it; ++it) {
+      protos::pbzero::GpuRenderStageEvent_Specifications_Description::Decoder
+          stage(it->data(), it->size());
+      if (stage.has_name()) {
+        gpu_render_stage_ids_.emplace_back(
+            context_->storage->InternString(stage.name()));
+      }
+    }
+  }
+
+  auto args_callback = [this, &event](ArgsTracker* args_tracker, RowId row_id) {
+    for (auto it = event.extra_data(); it; ++it) {
+      protos::pbzero::GpuRenderStageEvent_ExtraData_Decoder datum(it->data(),
+                                                                  it->size());
+      StringId name_id = context_->storage->InternString(datum.name());
+      StringId value = context_->storage->InternString(
+          datum.has_value() ? datum.value() : base::StringView());
+      args_tracker->AddArg(row_id, name_id, name_id, Variadic::String(value));
+    }
+  };
+
+  if (event.has_event_id()) {
+    size_t stage_id = static_cast<size_t>(event.stage_id());
+    StringId stage_name;
+    if (stage_id < gpu_render_stage_ids_.size()) {
+      stage_name = gpu_render_stage_ids_[stage_id];
+    } else {
+      char buffer[64];
+      snprintf(buffer, 64, "render stage(%zu)", stage_id);
+      stage_name = context_->storage->InternString(buffer);
+    }
+    const auto slice_id = context_->slice_tracker->Scoped(
+        ts, event.hw_queue_id(), RefType::kRefGpuId, 0, /* cat */
+        stage_name, static_cast<int64_t>(event.duration()), args_callback);
+
+    context_->storage->mutable_gpu_slice_table()->Insert(
+        tables::GpuSliceTable::Row(
+            slice_id.value(), static_cast<int64_t>(event.context()),
+            static_cast<int64_t>(event.render_target_handle()),
+            base::nullopt /*frame_id*/, event.submission_id(),
+            static_cast<uint32_t>(event.hw_queue_id())));
+  }
+}
+
+void GraphicsEventParser::ParseGraphicsFrameEvent(int64_t timestamp,
+                                                  ConstBytes blob) {
+  protos::pbzero::GraphicsFrameEvent_Decoder frame_event(blob.data, blob.size);
+  if (!frame_event.has_buffer_event()) {
+    return;
+  }
+
+  ConstBytes bufferBlob = frame_event.buffer_event();
+  protos::pbzero::GraphicsFrameEvent_BufferEvent_Decoder event(bufferBlob.data,
+                                                               bufferBlob.size);
+
+  if (!event.has_buffer_id()) {
+    context_->storage->IncrementStats(
+        stats::graphics_frame_event_parser_errors);
+    PERFETTO_ELOG("GraphicsFrameEvent with missing buffer id field.");
+    return;
+  }
+
+  StringId event_name_id = unknown_event_name_id_;
+  if (event.has_type()) {
+    const auto type = static_cast<size_t>(event.type());
+    if (type < event_type_name_ids_.size()) {
+      event_name_id = event_type_name_ids_[type];
+    } else {
+      context_->storage->IncrementStats(
+          stats::graphics_frame_event_parser_errors);
+      PERFETTO_ELOG("GraphicsFrameEvent with unknown type %zu.", type);
+    }
+  } else {
+    context_->storage->IncrementStats(
+        stats::graphics_frame_event_parser_errors);
+    PERFETTO_ELOG("GraphicsFrameEvent with missing type field.");
+  }
+
+  const uint32_t buffer_id = event.buffer_id();
+  StringId layer_name_id;
+
+  char buffer[4096];
+  const size_t layerNameMaxLength = 4000;
+  base::StringWriter track_name(buffer, sizeof(buffer));
+  if (event.has_layer_name()) {
+    const base::StringView layer_name(event.layer_name());
+    layer_name_id = context_->storage->InternString(layer_name);
+    track_name.AppendString(layer_name.substr(0, layerNameMaxLength));
+  } else {
+    layer_name_id = no_layer_name_name_id_;
+    track_name.AppendLiteral("unknown_layer");
+  }
+  track_name.AppendLiteral("[buffer:");
+  track_name.AppendUnsignedInt(buffer_id);
+  track_name.AppendChar(']');
+
+  const StringId track_name_id =
+      context_->storage->InternString(track_name.GetStringView());
+  const int64_t duration =
+      event.has_duration_ns() ? static_cast<int64_t>(event.duration_ns()) : 0;
+  const uint32_t frame_number =
+      event.has_frame_number() ? event.frame_number() : 0;
+
+  const TrackId track_id = context_->virtual_track_tracker->GetOrCreateTrack(
+      {VirtualTrackScope::kGlobal, 0 /* upid */, track_name_id.id,
+       graphics_event_scope_id_},
+      track_name_id);
+
+  context_->storage->mutable_gpu_track_table()->Insert(
+      tables::GpuTrackTable::Row(track_id, graphics_event_scope_id_));
+
+  const auto slice_id = context_->slice_tracker->Scoped(
+      timestamp, track_id, RefType::kRefTrack, 0 /* cat */, event_name_id,
+      duration, [this, layer_name_id](ArgsTracker* args_tracker, RowId row_id) {
+        args_tracker->AddArg(row_id, layer_name_key_id_, layer_name_key_id_,
+                             Variadic::String(layer_name_id));
+      });
+
+  if (slice_id) {
+    tables::GpuSliceTable::Row row;
+    row.slice_id = slice_id.value();
+    row.frame_id = frame_number;
+    context_->storage->mutable_gpu_slice_table()->Insert(row);
+  }
+}
+
+}  // namespace trace_processor
+}  // namespace perfetto
diff --git a/src/trace_processor/graphics_event_parser.h b/src/trace_processor/graphics_event_parser.h
new file mode 100644
index 0000000..7b28962
--- /dev/null
+++ b/src/trace_processor/graphics_event_parser.h
@@ -0,0 +1,60 @@
+/*
+ * 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_TRACE_PROCESSOR_GRAPHICS_EVENT_PARSER_H_
+#define SRC_TRACE_PROCESSOR_GRAPHICS_EVENT_PARSER_H_
+
+#include <vector>
+
+#include "perfetto/protozero/field.h"
+#include "src/trace_processor/trace_storage.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class TraceProcessorContext;
+
+// Class for parsing graphics related events.
+class GraphicsEventParser {
+ public:
+  using ConstBytes = protozero::ConstBytes;
+  explicit GraphicsEventParser(TraceProcessorContext*);
+  ~GraphicsEventParser();
+
+  void ParseGpuCounterEvent(int64_t ts, ConstBytes);
+  void ParseGpuRenderStageEvent(int64_t ts, ConstBytes);
+  void ParseGraphicsFrameEvent(int64_t timestamp, ConstBytes);
+
+ private:
+  TraceProcessorContext* const context_;
+  // For GpuCounterEvent
+  std::unordered_map<uint32_t, const TraceStorage::CounterDefinitions::Id>
+      gpu_counter_ids_;
+  // For GpuRenderStageEvent
+  std::vector<StringId> gpu_hw_queue_ids_;
+  std::vector<StringId> gpu_render_stage_ids_;
+  // For GraphicsFrameEvent
+  const StringId graphics_event_scope_id_;
+  const StringId unknown_event_name_id_;
+  const StringId no_layer_name_name_id_;
+  const StringId layer_name_key_id_;
+  std::array<StringId, 11> event_type_name_ids_;
+};
+
+}  // namespace trace_processor
+}  // namespace perfetto
+
+#endif  // SRC_TRACE_PROCESSOR_GRAPHICS_EVENT_PARSER_H_
diff --git a/src/trace_processor/graphics_frame_event_parser.cc b/src/trace_processor/graphics_frame_event_parser.cc
deleted file mode 100644
index 6913771..0000000
--- a/src/trace_processor/graphics_frame_event_parser.cc
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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.
- */
-
-#include "src/trace_processor/graphics_frame_event_parser.h"
-
-#include "perfetto/protozero/field.h"
-#include "src/trace_processor/args_tracker.h"
-#include "src/trace_processor/slice_tracker.h"
-#include "src/trace_processor/trace_processor_context.h"
-#include "src/trace_processor/virtual_track_tracker.h"
-
-#include "protos/perfetto/trace/android/graphics_frame_event.pbzero.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-using BufferEventType = protos::pbzero::GraphicsFrameEvent_BufferEventType;
-using ConstBytes = protozero::ConstBytes;
-
-GraphicsFrameEventParser::~GraphicsFrameEventParser() = default;
-
-GraphicsFrameEventParser::GraphicsFrameEventParser(
-    TraceProcessorContext* context)
-    : context_(context),
-      graphics_event_scope_id_(
-          context->storage->InternString("graphics_frame_event.scope")),
-      unspecified_event_name_id_(
-          context->storage->InternString("unspecified_event")),
-      dequeue_name_id_(context->storage->InternString("Dequeue")),
-      queue_name_id_(context->storage->InternString("Queue")),
-      post_name_id_(context->storage->InternString("Post")),
-      acquire_name_id_(context->storage->InternString("AcquireFenceSignaled")),
-      latch_name_id_(context->storage->InternString("Latch")),
-      hwc_composition_queued_name_id_(
-          context->storage->InternString("HWCCompositionQueued")),
-      fallback_composition_name_id_(
-          context->storage->InternString("FallbackComposition")),
-      present_name_id_(context->storage->InternString("PresentFenceSignaled")),
-      release_name_id_(context->storage->InternString("ReleaseFenceSignaled")),
-      modify_name_id_(context->storage->InternString("Modify")),
-      unknown_event_name_id_(context->storage->InternString("unknown_event")),
-      no_layer_name_name_id_(context->storage->InternString("no_layer_name")),
-      layer_name_key_id_(context->storage->InternString("layer_name")),
-      frame_number_key_id_(context->storage->InternString("frame_number")),
-      event_type_name_ids_{
-          {unspecified_event_name_id_ /* UNSPECIFIED */,
-           dequeue_name_id_ /* DEQUEUE */, queue_name_id_ /* QUEUE */,
-           post_name_id_ /* POST */, acquire_name_id_ /* ACQUIRE_FENCE */,
-           latch_name_id_ /* LATCH */,
-           hwc_composition_queued_name_id_ /* HWC_COMPOSITION_QUEUED */,
-           fallback_composition_name_id_ /* FALLBACK_COMPOSITION */,
-           present_name_id_ /* PRESENT_FENCE */,
-           release_name_id_ /* RELEASE_FENCE */,
-           modify_name_id_ /* MODIFY */}} {}
-
-void GraphicsFrameEventParser::ParseEvent(int64_t timestamp, ConstBytes blob) {
-  protos::pbzero::GraphicsFrameEvent_Decoder frame_event(blob.data, blob.size);
-  if (!frame_event.has_buffer_event()) {
-    return;
-  }
-
-  ConstBytes bufferBlob = frame_event.buffer_event();
-  protos::pbzero::GraphicsFrameEvent_BufferEvent_Decoder event(bufferBlob.data,
-                                                               bufferBlob.size);
-
-  if (!event.has_buffer_id()) {
-    context_->storage->IncrementStats(stats::graphics_frame_event_parser_errors);
-    PERFETTO_ELOG("GraphicsFrameEvent with missing buffer id field.");
-    return;
-  }
-
-  StringId event_name_id = unknown_event_name_id_;
-  if (event.has_type()) {
-    const auto type = static_cast<size_t>(event.type());
-    if (type < event_type_name_ids_.size()) {
-      event_name_id = event_type_name_ids_[type];
-    } else {
-      context_->storage->IncrementStats(stats::graphics_frame_event_parser_errors);
-      PERFETTO_ELOG("GraphicsFrameEvent with unknown type %zu.", type);
-    }
-  } else {
-    context_->storage->IncrementStats(stats::graphics_frame_event_parser_errors);
-    PERFETTO_ELOG("GraphicsFrameEvent with missing type field.");
-  }
-
-  const uint32_t buffer_id = event.buffer_id();
-  StringId layer_name_id;
-
-  char buffer[4096];
-  const size_t layerNameMaxLength = 4000;
-  base::StringWriter track_name(buffer, sizeof(buffer));
-  if (event.has_layer_name()) {
-    const base::StringView layer_name(event.layer_name());
-    layer_name_id = context_->storage->InternString(layer_name);
-    track_name.AppendString(layer_name.substr(0, layerNameMaxLength));
-  } else {
-    layer_name_id = no_layer_name_name_id_;
-    track_name.AppendLiteral("unknown_layer");
-  }
-  track_name.AppendLiteral("[buffer:");
-  track_name.AppendUnsignedInt(buffer_id);
-  track_name.AppendChar(']');
-
-  const StringId track_name_id =
-      context_->storage->InternString(track_name.GetStringView());
-  const int64_t duration =
-      event.has_duration_ns() ? static_cast<int64_t>(event.duration_ns()) : 0;
-  const uint32_t frame_number =
-      event.has_frame_number() ? event.frame_number() : 0;
-
-  const TrackId track_id = context_->virtual_track_tracker->GetOrCreateTrack(
-      {VirtualTrackScope::kGlobal, 0 /* upid */, track_name_id.id,
-       graphics_event_scope_id_},
-      track_name_id);
-
-  context_->storage->mutable_gpu_track_table()->Insert(
-      tables::GpuTrackTable::Row(track_id, graphics_event_scope_id_));
-
-  const auto slice_id = context_->slice_tracker->Scoped(
-      timestamp, track_id, RefType::kRefTrack, 0 /* cat */, event_name_id,
-      duration, [this, layer_name_id](ArgsTracker* args_tracker, RowId row_id) {
-        args_tracker->AddArg(row_id, layer_name_key_id_, layer_name_key_id_,
-                             Variadic::String(layer_name_id));
-      });
-
-  if (slice_id) {
-    tables::GpuSliceTable::Row row;
-    row.slice_id = slice_id.value();
-    row.frame_id = frame_number;
-    context_->storage->mutable_gpu_slice_table()->Insert(row);
-  }
-}
-
-}  // namespace trace_processor
-}  // namespace perfetto
diff --git a/src/trace_processor/graphics_frame_event_parser.h b/src/trace_processor/graphics_frame_event_parser.h
deleted file mode 100644
index 12ae908..0000000
--- a/src/trace_processor/graphics_frame_event_parser.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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_TRACE_PROCESSOR_GRAPHICS_FRAME_EVENT_PARSER_H_
-#define SRC_TRACE_PROCESSOR_GRAPHICS_FRAME_EVENT_PARSER_H_
-
-#include <vector>
-
-#include "perfetto/protozero/field.h"
-#include "src/trace_processor/trace_storage.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-class TraceProcessorContext;
-
-// Class for parsing GraphicFrameEvents.
-class GraphicsFrameEventParser {
- public:
-  explicit GraphicsFrameEventParser(TraceProcessorContext*);
-  ~GraphicsFrameEventParser();
-
-  void ParseEvent(int64_t timestamp, protozero::ConstBytes);
-
- private:
-  TraceProcessorContext* const context_;
-  const StringId graphics_event_scope_id_;
-  const StringId unspecified_event_name_id_;
-  const StringId dequeue_name_id_;
-  const StringId queue_name_id_;
-  const StringId post_name_id_;
-  const StringId acquire_name_id_;
-  const StringId latch_name_id_;
-  const StringId hwc_composition_queued_name_id_;
-  const StringId fallback_composition_name_id_;
-  const StringId present_name_id_;
-  const StringId release_name_id_;
-  const StringId modify_name_id_;
-  const StringId unknown_event_name_id_;
-  const StringId no_layer_name_name_id_;
-  const StringId layer_name_key_id_;
-  const StringId frame_number_key_id_;
-
-  std::array<StringId, 11> event_type_name_ids_;
-};
-
-}  // namespace trace_processor
-}  // namespace perfetto
-
-#endif  // SRC_TRACE_PROCESSOR_GRAPHICS_FRAME_EVENT_PARSER_H_
diff --git a/src/trace_processor/metrics/metrics.h b/src/trace_processor/metrics/metrics.h
index 771bb16..31d0e78 100644
--- a/src/trace_processor/metrics/metrics.h
+++ b/src/trace_processor/metrics/metrics.h
@@ -158,7 +158,7 @@
   const ProtoDescriptor* desc;
 };
 
-// This funciton implements all the proto creation functions.
+// This function implements all the proto creation functions.
 void BuildProto(sqlite3_context* ctx, int argc, sqlite3_value** argv);
 
 // Context struct for the below function.
diff --git a/src/trace_processor/proto_trace_parser.cc b/src/trace_processor/proto_trace_parser.cc
index c059eee..f642ab0 100644
--- a/src/trace_processor/proto_trace_parser.cc
+++ b/src/trace_processor/proto_trace_parser.cc
@@ -43,7 +43,6 @@
 
 #include "perfetto/ext/base/string_writer.h"
 #include "protos/perfetto/common/android_log_constants.pbzero.h"
-#include "protos/perfetto/common/gpu_counter_descriptor.pbzero.h"
 #include "protos/perfetto/common/trace_stats.pbzero.h"
 #include "protos/perfetto/trace/android/android_log.pbzero.h"
 #include "protos/perfetto/trace/android/packages_list.pbzero.h"
@@ -65,8 +64,6 @@
 #include "protos/perfetto/trace/ftrace/signal.pbzero.h"
 #include "protos/perfetto/trace/ftrace/systrace.pbzero.h"
 #include "protos/perfetto/trace/ftrace/task.pbzero.h"
-#include "protos/perfetto/trace/gpu/gpu_counter_event.pbzero.h"
-#include "protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.h"
 #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
 #include "protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h"
 #include "protos/perfetto/trace/power/battery_counters.pbzero.h"
@@ -214,7 +211,7 @@
 
 ProtoTraceParser::ProtoTraceParser(TraceProcessorContext* context)
     : context_(context),
-      graphics_frame_event_parser_(new GraphicsFrameEventParser(context_)),
+      graphics_event_parser_(new GraphicsEventParser(context_)),
       utid_name_id_(context->storage->InternString("utid")),
       sched_wakeup_name_id_(context->storage->InternString("sched_wakeup")),
       sched_waking_name_id_(context->storage->InternString("sched_waking")),
@@ -460,11 +457,13 @@
   }
 
   if (packet.has_gpu_counter_event()) {
-    ParseGpuCounterEvent(ts, packet.gpu_counter_event());
+    graphics_event_parser_->ParseGpuCounterEvent(ts,
+                                                 packet.gpu_counter_event());
   }
 
   if (packet.has_gpu_render_stage_event()) {
-    ParseGpuRenderStageEvent(ts, packet.gpu_render_stage_event());
+    graphics_event_parser_->ParseGpuRenderStageEvent(
+        ts, packet.gpu_render_stage_event());
   }
 
   if (packet.has_packages_list()) {
@@ -472,7 +471,8 @@
   }
 
   if (packet.has_graphics_frame_event()) {
-    graphics_frame_event_parser_->ParseEvent(ts, packet.graphics_frame_event());
+    graphics_event_parser_->ParseGraphicsFrameEvent(
+        ts, packet.graphics_frame_event());
   }
 
   if (packet.has_appended_data()) {
@@ -1444,7 +1444,7 @@
 }
 
 void ProtoTraceParser::ParseProfilePacket(
-    int64_t ts,
+    int64_t,
     ProtoIncrementalState::PacketSequenceState* sequence_state,
     ConstBytes blob) {
   protos::pbzero::ProfilePacket::Decoder packet(blob.data, blob.size);
@@ -1499,7 +1499,7 @@
 
       HeapProfileTracker::SourceAllocation src_allocation;
       src_allocation.pid = entry.pid();
-      src_allocation.timestamp = ts;
+      src_allocation.timestamp = static_cast<int64_t>(entry.timestamp());
       src_allocation.callstack_id = sample.callstack_id();
       src_allocation.self_allocated = sample.self_allocated();
       src_allocation.self_freed = sample.self_freed();
@@ -2493,151 +2493,6 @@
     context_->storage->IncrementStats(stats::metatrace_overruns);
 }
 
-void ProtoTraceParser::ParseGpuCounterEvent(int64_t ts, ConstBytes blob) {
-  protos::pbzero::GpuCounterEvent::Decoder event(blob.data, blob.size);
-
-  protos::pbzero::GpuCounterDescriptor::Decoder descriptor(
-      event.counter_descriptor());
-  // Add counter spec to ID map.
-  for (auto it = descriptor.specs(); it; ++it) {
-    protos::pbzero::GpuCounterDescriptor_GpuCounterSpec::Decoder spec(
-        it->data(), it->size());
-    if (!spec.has_counter_id()) {
-      PERFETTO_ELOG("Counter spec missing counter id");
-      context_->storage->IncrementStats(stats::gpu_counters_invalid_spec);
-      continue;
-    }
-    if (!spec.has_name()) {
-      context_->storage->IncrementStats(stats::gpu_counters_invalid_spec);
-      continue;
-    }
-
-    auto counter_id = spec.counter_id();
-    auto name = spec.name();
-    if (gpu_counter_ids_.find(counter_id) == gpu_counter_ids_.end()) {
-      auto desc = spec.description();
-
-      StringId unit_id = 0;
-      if (spec.has_numerator_units() || spec.has_denominator_units()) {
-        char buffer[1024];
-        base::StringWriter unit(buffer, sizeof(buffer));
-        for (auto numer = spec.numerator_units(); numer; ++numer) {
-          if (unit.pos()) {
-            unit.AppendChar(':');
-          }
-          unit.AppendInt(numer->as_int64());
-        }
-        char sep = '/';
-        for (auto denom = spec.denominator_units(); denom; ++denom) {
-          unit.AppendChar(sep);
-          unit.AppendInt(denom->as_int64());
-          sep = ':';
-        }
-        unit_id = context_->storage->InternString(unit.GetStringView());
-      }
-
-      auto name_id = context_->storage->InternString(name);
-      auto desc_id = context_->storage->InternString(desc);
-      auto* definitions = context_->storage->mutable_counter_definitions();
-      auto defn_id = definitions->AddCounterDefinition(name_id,
-                                                       0,
-                                                       RefType::kRefGpuId,
-                                                       desc_id,
-                                                       unit_id);
-      gpu_counter_ids_.emplace(counter_id, defn_id);
-    } else {
-      // Either counter spec was repeated or it came after counter data.
-      PERFETTO_ELOG("Duplicated counter spec found. (counter_id=%d, name=%s)",
-                    counter_id, name.ToStdString().c_str());
-      context_->storage->IncrementStats(stats::gpu_counters_invalid_spec);
-    }
-  }
-
-  for (auto it = event.counters(); it; ++it) {
-    protos::pbzero::GpuCounterEvent_GpuCounter::Decoder counter(it->data(),
-                                                                it->size());
-    if (counter.has_counter_id() &&
-        (counter.has_int_value() || counter.has_double_value())) {
-      auto counter_id = counter.counter_id();
-      // Check missing counter_id
-      if (gpu_counter_ids_.find(counter_id) == gpu_counter_ids_.end()) {
-        char buffer[64];
-        base::StringWriter writer(buffer, sizeof(buffer));
-        writer.AppendString("gpu_counter(");
-        writer.AppendUnsignedInt(counter_id);
-        writer.AppendString(")");
-        auto name_id = context_->storage->InternString(writer.GetStringView());
-        auto* definitions = context_->storage->mutable_counter_definitions();
-        auto defn_id = definitions->AddCounterDefinition(name_id,
-                                                         0,
-                                                         RefType::kRefGpuId);
-        gpu_counter_ids_.emplace(counter_id, defn_id);
-        context_->storage->IncrementStats(stats::gpu_counters_missing_spec);
-      }
-      if (counter.has_int_value()) {
-        context_->event_tracker->PushCounter(ts, counter.int_value(),
-                                             gpu_counter_ids_[counter_id]);
-      } else {
-        context_->event_tracker->PushCounter(ts, counter.double_value(),
-                                             gpu_counter_ids_[counter_id]);
-      }
-    }
-  }
-}
-
-void ProtoTraceParser::ParseGpuRenderStageEvent(int64_t ts, ConstBytes blob) {
-  protos::pbzero::GpuRenderStageEvent::Decoder event(blob.data, blob.size);
-
-  if (event.has_specifications()) {
-    protos::pbzero::GpuRenderStageEvent_Specifications::Decoder spec(
-        event.specifications().data, event.specifications().size);
-    for (auto it = spec.hw_queue(); it; ++it) {
-      protos::pbzero::GpuRenderStageEvent_Specifications_Description::Decoder
-          hw_queue(it->data(), it->size());
-      if (hw_queue.has_name()) {
-        // TODO: create vtrack for each HW queue when it's ready.
-        gpu_hw_queue_ids_.emplace_back(
-            context_->storage->InternString(hw_queue.name()));
-      }
-    }
-    for (auto it = spec.stage(); it; ++it) {
-      protos::pbzero::GpuRenderStageEvent_Specifications_Description::Decoder
-          stage(it->data(), it->size());
-      if (stage.has_name()) {
-        gpu_render_stage_ids_.emplace_back(
-            context_->storage->InternString(stage.name()));
-      }
-    }
-  }
-
-  auto args_callback = [this, &event](
-                           ArgsTracker* args_tracker, RowId row_id) {
-    for (auto it = event.extra_data(); it; ++it) {
-      protos::pbzero::GpuRenderStageEvent_ExtraData_Decoder
-          datum(it->data(), it->size());
-      StringId name_id = context_->storage->InternString(datum.name());
-      StringId value = context_->storage->InternString(
-          datum.has_value() ? datum.value() : base::StringView());
-      args_tracker->AddArg(row_id, name_id, name_id, Variadic::String(value));
-    }
-  };
-
-  if (event.has_event_id()) {
-    size_t stage_id = static_cast<size_t>(event.stage_id());
-    StringId stage_name;
-    if (stage_id < gpu_render_stage_ids_.size()) {
-      stage_name = gpu_render_stage_ids_[stage_id];
-    } else {
-      char buffer[64];
-      snprintf(buffer, 64, "render stage(%zu)", stage_id);
-      stage_name = context_->storage->InternString(buffer);
-    }
-    context_->slice_tracker->Scoped(
-        ts, event.hw_queue_id(), RefType::kRefGpuId, 0, /* cat */
-        stage_name, static_cast<int64_t>(event.duration()), args_callback);
-  }
-}
-
 void ProtoTraceParser::ParseAndroidPackagesList(ConstBytes blob) {
   protos::pbzero::PackagesList::Decoder pkg_list(blob.data, blob.size);
   context_->storage->SetStats(stats::packages_list_has_read_errors,
diff --git a/src/trace_processor/proto_trace_parser.h b/src/trace_processor/proto_trace_parser.h
index d6ee5ee..3e6fb05 100644
--- a/src/trace_processor/proto_trace_parser.h
+++ b/src/trace_processor/proto_trace_parser.h
@@ -25,7 +25,7 @@
 #include "perfetto/ext/base/string_view.h"
 #include "perfetto/protozero/field.h"
 #include "src/trace_processor/ftrace_descriptors.h"
-#include "src/trace_processor/graphics_frame_event_parser.h"
+#include "src/trace_processor/graphics_event_parser.h"
 #include "src/trace_processor/proto_incremental_state.h"
 #include "src/trace_processor/slice_tracker.h"
 #include "src/trace_processor/trace_blob_view.h"
@@ -133,8 +133,6 @@
   void ParseChromeBenchmarkMetadata(ConstBytes);
   void ParseChromeEvents(int64_t ts, ConstBytes);
   void ParseMetatraceEvent(int64_t ts, ConstBytes);
-  void ParseGpuCounterEvent(int64_t ts, ConstBytes);
-  void ParseGpuRenderStageEvent(int64_t ts, ConstBytes);
   void ParseAndroidPackagesList(ConstBytes);
   void ParseLogMessage(ConstBytes,
                        ProtoIncrementalState::PacketSequenceState*,
@@ -149,7 +147,7 @@
 
  private:
   TraceProcessorContext* context_;
-  std::unique_ptr<GraphicsFrameEventParser> graphics_frame_event_parser_;
+  std::unique_ptr<GraphicsEventParser> graphics_event_parser_;
 
   const StringId utid_name_id_;
   const StringId sched_wakeup_name_id_;
@@ -212,9 +210,6 @@
   std::vector<StringId> vmstat_strs_id_;
   std::vector<StringId> rss_members_;
   std::vector<StringId> power_rails_strs_id_;
-  std::unordered_map<uint32_t, const TraceStorage::CounterDefinitions::Id> gpu_counter_ids_;
-  std::vector<StringId> gpu_hw_queue_ids_;
-  std::vector<StringId> gpu_render_stage_ids_;
 
   struct FtraceMessageStrings {
     // The string id of name of the event field (e.g. sched_switch's id).
diff --git a/src/trace_processor/syscall_tracker.h b/src/trace_processor/syscall_tracker.h
index 4c62db0..76523dd 100644
--- a/src/trace_processor/syscall_tracker.h
+++ b/src/trace_processor/syscall_tracker.h
@@ -80,7 +80,7 @@
   }
 
   // This is table from platform specific syscall number directly to
-  // the relevent StringId (this avoids having to always do two conversions).
+  // the relevant StringId (this avoids having to always do two conversions).
   std::array<StringId, kMaxSyscalls> arch_syscall_to_string_id_{};
   StringId sys_write_string_id_ = std::numeric_limits<StringId>::max();
 };
diff --git a/src/trace_processor/tables/BUILD.gn b/src/trace_processor/tables/BUILD.gn
index ba41d12..ab79c88 100644
--- a/src/trace_processor/tables/BUILD.gn
+++ b/src/trace_processor/tables/BUILD.gn
@@ -16,6 +16,7 @@
   sources = [
     "macros.h",
     "macros_internal.h",
+    "profiler_tables.h",
     "slice_tables.h",
     "track_tables.h",
   ]
diff --git a/src/trace_processor/tables/slice_tables.h b/src/trace_processor/tables/slice_tables.h
index 57dc822..9001c47 100644
--- a/src/trace_processor/tables/slice_tables.h
+++ b/src/trace_processor/tables/slice_tables.h
@@ -28,9 +28,9 @@
   PERFETTO_TP_ROOT_TABLE(PARENT, C)                 \
   C(uint32_t, slice_id)                             \
   C(base::Optional<int64_t>, context_id)            \
-  C(base::Optional<uint32_t>, render_target)        \
+  C(base::Optional<int64_t>, render_target)         \
   C(base::Optional<uint32_t>, frame_id)             \
-  C(base::Optional<uint32_t>, job_id)               \
+  C(base::Optional<uint32_t>, submission_id)        \
   C(base::Optional<uint32_t>, hw_queue_id)
 
 PERFETTO_TP_TABLE(PERFETTO_TP_GPU_SLICES_DEF);
diff --git a/src/trace_processor/trace_storage.h b/src/trace_processor/trace_storage.h
index 6d08522..528c2a7 100644
--- a/src/trace_processor/trace_storage.h
+++ b/src/trace_processor/trace_storage.h
@@ -1280,11 +1280,11 @@
 
   const StringPool& string_pool() const { return string_pool_; }
 
-  // |unique_processes_| always contains at least 1 element becuase the 0th ID
+  // |unique_processes_| always contains at least 1 element because the 0th ID
   // is reserved to indicate an invalid process.
   size_t process_count() const { return unique_processes_.size(); }
 
-  // |unique_threads_| always contains at least 1 element becuase the 0th ID
+  // |unique_threads_| always contains at least 1 element because the 0th ID
   // is reserved to indicate an invalid thread.
   size_t thread_count() const { return unique_threads_.size(); }
 
diff --git a/src/traced/probes/ftrace/BUILD.gn b/src/traced/probes/ftrace/BUILD.gn
index 719f316..eddd44d 100644
--- a/src/traced/probes/ftrace/BUILD.gn
+++ b/src/traced/probes/ftrace/BUILD.gn
@@ -114,6 +114,8 @@
     "atrace_hal_wrapper.h",
     "atrace_wrapper.cc",
     "atrace_wrapper.h",
+    "compact_sched.cc",
+    "compact_sched.h",
     "cpu_reader.cc",
     "cpu_reader.h",
     "cpu_stats_parser.cc",
diff --git a/src/traced/probes/ftrace/compact_sched.cc b/src/traced/probes/ftrace/compact_sched.cc
new file mode 100644
index 0000000..85ab487
--- /dev/null
+++ b/src/traced/probes/ftrace/compact_sched.cc
@@ -0,0 +1,189 @@
+/*
+ * 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.
+ */
+
+#include "src/traced/probes/ftrace/compact_sched.h"
+
+#include <stdint.h>
+
+#include "perfetto/ext/base/optional.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
+#include "protos/perfetto/trace/ftrace/sched.pbzero.h"
+#include "src/traced/probes/ftrace/event_info_constants.h"
+#include "src/traced/probes/ftrace/ftrace_config.h"
+
+namespace perfetto {
+
+namespace {
+
+// Pre-parse the format of sched_switch, checking if our simplifying
+// assumptions about possible widths/signedness hold, and record the subset
+// of the format that will be used during parsing.
+base::Optional<CompactSchedSwitchFormat> ValidateSchedSwitchFormat(
+    const Event& event) {
+  using protos::pbzero::SchedSwitchFtraceEvent;
+
+  CompactSchedSwitchFormat switch_format;
+  switch_format.event_id = event.ftrace_event_id;
+
+  // We make a compile-time buffer capacity decision based on the expected event
+  // size per a set of pages. Check that the assumption holds.
+  if (event.size < CompactSchedBundleState::kMinSupportedSchedSwitchSize) {
+    return base::nullopt;
+  }
+  switch_format.size = event.size;
+
+  bool prev_state_valid = false;
+  bool next_pid_valid = false;
+  bool next_prio_valid = false;
+  bool next_comm_valid = false;
+  for (const auto& field : event.fields) {
+    switch (field.proto_field_id) {
+      case SchedSwitchFtraceEvent::kPrevStateFieldNumber:
+        switch_format.prev_state_offset = field.ftrace_offset;
+        switch_format.prev_state_type = field.ftrace_type;
+
+        // kernel type: long
+        prev_state_valid = (field.ftrace_type == kFtraceInt32 ||
+                            field.ftrace_type == kFtraceInt64);
+        break;
+
+      case SchedSwitchFtraceEvent::kNextPidFieldNumber:
+        switch_format.next_pid_offset = field.ftrace_offset;
+        switch_format.next_pid_type = field.ftrace_type;
+
+        // kernel type: pid_t
+        next_pid_valid = (field.ftrace_type == kFtracePid32);
+        break;
+
+      case SchedSwitchFtraceEvent::kNextPrioFieldNumber:
+        switch_format.next_prio_offset = field.ftrace_offset;
+        switch_format.next_prio_type = field.ftrace_type;
+
+        // kernel type: int
+        next_prio_valid = (field.ftrace_type == kFtraceInt32);
+        break;
+
+      case SchedSwitchFtraceEvent::kNextCommFieldNumber:
+        switch_format.next_comm_offset = field.ftrace_offset;
+
+        next_comm_valid =
+            (field.ftrace_type == kFtraceFixedCString &&
+             field.ftrace_size == CompactSchedBundleState::kExpectedCommLength);
+        break;
+      default:
+        break;
+    }
+  }
+
+  if (!prev_state_valid || !next_pid_valid || !next_prio_valid ||
+      !next_comm_valid) {
+    PERFETTO_ELOG("unexpected sched_switch format");
+    return base::nullopt;
+  }
+
+  return base::make_optional(switch_format);
+}
+
+}  // namespace
+
+// TODO(rsavitski): could avoid looping over all events if the caller did the
+// work to remember the relevant events (translation table construction already
+// loops over them).
+CompactSchedEventFormat ValidateFormatForCompactSched(
+    const std::vector<Event>& events) {
+  using protos::pbzero::FtraceEvent;
+
+  base::Optional<CompactSchedSwitchFormat> switch_format;
+  for (const Event& event : events) {
+    if (event.proto_field_id == FtraceEvent::kSchedSwitchFieldNumber) {
+      switch_format = ValidateSchedSwitchFormat(event);
+    }
+  }
+
+  if (switch_format.has_value()) {
+    return CompactSchedEventFormat{/*format_valid=*/true,
+                                   switch_format.value()};
+  } else {
+    return CompactSchedEventFormat{/*format_valid=*/false,
+                                   CompactSchedSwitchFormat{}};
+  }
+}
+
+CompactSchedEventFormat InvalidCompactSchedEventFormatForTesting() {
+  return CompactSchedEventFormat{/*format_valid=*/false,
+                                 CompactSchedSwitchFormat{}};
+}
+
+// TODO(rsavitski): find the correct place in the trace for, and method of,
+// reporting rejection of compact_sched due to compile-time assumptions not
+// holding at runtime.
+// TODO(rsavitski): consider checking if the ftrace config correctly enables
+// sched_switch, for at least an informative print for now?
+CompactSchedConfig CreateCompactSchedConfig(
+    const FtraceConfig& request,
+    const CompactSchedEventFormat& compact_format) {
+  if (!request.compact_sched().enabled())
+    return CompactSchedConfig{/*enabled=*/false};
+
+  if (!compact_format.format_valid)
+    return CompactSchedConfig{/*enabled=*/false};
+
+  return CompactSchedConfig{/*enabled=*/true};
+}
+
+CompactSchedConfig EnabledCompactSchedConfigForTesting() {
+  return CompactSchedConfig{/*enabled=*/true};
+}
+
+CompactSchedConfig DisabledCompactSchedConfigForTesting() {
+  return CompactSchedConfig{/*enabled=*/false};
+}
+
+// Sanity check size of stack-allocated bundle state.
+static_assert(sizeof(CompactSchedBundleState) <= 1 << 20,
+              "CompactSchedBundleState excessively large (used on the stack).");
+
+void CompactSchedBundleState::WriteAndReset(
+    protos::pbzero::FtraceEventBundle* bundle) {
+  // If we buffered at least one event (using the interner as a proxy),
+  // write the state out.
+  if (interned_switch_comms_size_ > 0) {
+    auto compact_out = bundle->set_compact_sched();
+
+    compact_out->set_switch_timestamp(switch_timestamp_);
+    compact_out->set_switch_next_pid(switch_next_pid_);
+    compact_out->set_switch_prev_state(switch_prev_state_);
+    compact_out->set_switch_next_prio(switch_next_prio_);
+
+    for (size_t i = 0; i < interned_switch_comms_size_; i++) {
+      compact_out->add_switch_next_comm_table(interned_switch_comms_[i].data(),
+                                              interned_switch_comms_[i].size());
+    }
+    compact_out->set_switch_next_comm_index(switch_next_comm_index_);
+  }
+
+  // Reset internal state.
+  last_switch_timestamp_ = 0;
+  switch_timestamp_.Reset();
+  switch_next_pid_.Reset();
+  switch_prev_state_.Reset();
+  switch_next_prio_.Reset();
+  switch_next_comm_index_.Reset();
+  intern_buf_write_pos_ = 0;
+  interned_switch_comms_size_ = 0;
+}
+
+}  // namespace perfetto
diff --git a/src/traced/probes/ftrace/compact_sched.h b/src/traced/probes/ftrace/compact_sched.h
new file mode 100644
index 0000000..029649e
--- /dev/null
+++ b/src/traced/probes/ftrace/compact_sched.h
@@ -0,0 +1,188 @@
+/*
+ * 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_TRACED_PROBES_FTRACE_COMPACT_SCHED_H_
+#define SRC_TRACED_PROBES_FTRACE_COMPACT_SCHED_H_
+
+#include <stdint.h>
+
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/protozero/packed_repeated_fields.h"
+#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
+#include "src/traced/probes/ftrace/event_info_constants.h"
+#include "src/traced/probes/ftrace/ftrace_config.h"
+
+namespace perfetto {
+
+// The subset of the sched_switch event's format that is used when parsing &
+// encoding into the compact format.
+struct CompactSchedSwitchFormat {
+  uint32_t event_id;
+  uint16_t size;
+
+  uint16_t next_pid_offset;
+  FtraceFieldType next_pid_type;
+  uint16_t next_prio_offset;
+  FtraceFieldType next_prio_type;
+  uint16_t prev_state_offset;
+  FtraceFieldType prev_state_type;
+  uint16_t next_comm_offset;
+};
+
+// Pre-parsed format of a subset of scheduling events, for use during ftrace
+// parsing if compact encoding is enabled. Holds a flag, |format_valid| to
+// state whether the compile-time assumptions about the format held at runtime.
+// If they didn't, we cannot use the compact encoding.
+struct CompactSchedEventFormat {
+  // If false, the rest of the struct is considered invalid.
+  const bool format_valid;
+  const CompactSchedSwitchFormat sched_switch;
+};
+
+CompactSchedEventFormat ValidateFormatForCompactSched(
+    const std::vector<Event>& events);
+
+CompactSchedEventFormat InvalidCompactSchedEventFormatForTesting();
+
+// Compact encoding configuration used at ftrace reading & parsing time.
+struct CompactSchedConfig {
+  CompactSchedConfig(bool _enabled) : enabled(_enabled) {}
+
+  // If true, and sched_switch event is enabled, encode it in a compact format
+  // instead of the normal form.
+  const bool enabled = false;
+};
+
+CompactSchedConfig CreateCompactSchedConfig(
+    const FtraceConfig& request,
+    const CompactSchedEventFormat& compact_format);
+
+CompactSchedConfig EnabledCompactSchedConfigForTesting();
+CompactSchedConfig DisabledCompactSchedConfigForTesting();
+
+// Mutable state for buffering parts of scheduling events, that can later be
+// written out in a compact format with |WriteAndReset|. Used by the ftrace
+// reader, allocated on the stack.
+class CompactSchedBundleState {
+ public:
+  // Most of the state is stack-allocated, with a compile-time
+  // size. We work in batches of pages (see kParsingBufferSizePages in
+  // ftrace_controller.cc), and assume a minimum size of a sched event as
+  // written by the kernel (validated at runtime). We therefore can calculate
+  // the maximum necessary capacity for a given parsing buffer size (as
+  // statically asserted in ftrace_controller.cc).
+  // Note: be careful not to align the individual buffers at a multiple of the
+  // cache size.
+  // TODO(rsavitski): this will need a slight rework once we add sched_waking,
+  // as it'll be the min size of the two events.
+  static constexpr size_t kMaxElements = 2560;
+  static constexpr size_t kMinSupportedSchedSwitchSize = 56;
+  static constexpr size_t kExpectedCommLength = 16;
+
+  protozero::StackAllocated<protozero::PackedVarIntBuffer, kMaxElements>*
+  switch_timestamp() {
+    return &switch_timestamp_;
+  }
+
+  protozero::StackAllocated<protozero::PackedVarIntBuffer, kMaxElements>*
+  switch_prev_state() {
+    return &switch_prev_state_;
+  }
+
+  protozero::StackAllocated<protozero::PackedVarIntBuffer, kMaxElements>*
+  switch_next_pid() {
+    return &switch_next_pid_;
+  }
+
+  protozero::StackAllocated<protozero::PackedVarIntBuffer, kMaxElements>*
+  switch_next_prio() {
+    return &switch_next_prio_;
+  }
+
+  size_t interned_switch_comms_size() const {
+    return interned_switch_comms_size_;
+  }
+
+  inline void AppendSwitchTimestamp(uint64_t timestamp) {
+    switch_timestamp_.Append(timestamp - last_switch_timestamp_);
+    last_switch_timestamp_ = timestamp;
+  }
+
+  // TODO(rsavitski): see if we can use the fact that comms are <16 bytes
+  // long when comparing them.
+  void InternSwitchNextComm(const char* ptr) {
+    // Linearly scan existing string views, ftrace reader will
+    // make sure this set doesn't grow too large.
+    base::StringView transient_view(ptr);
+    for (size_t i = 0; i < interned_switch_comms_size_; i++) {
+      if (transient_view == interned_switch_comms_[i]) {
+        switch_next_comm_index_.Append(i);
+        return;
+      }
+    }
+
+    // Unique next_comm, intern it. Null byte is not copied over.
+    char* start = intern_buf_ + intern_buf_write_pos_;
+    size_t size = transient_view.size();
+    memcpy(start, ptr, size);
+    intern_buf_write_pos_ += size;
+
+    switch_next_comm_index_.Append(interned_switch_comms_size_);
+    base::StringView safe_view(start, size);
+    interned_switch_comms_[interned_switch_comms_size_++] = safe_view;
+
+    PERFETTO_DCHECK(intern_buf_write_pos_ <= sizeof(intern_buf_));
+  }
+
+  // Writes out the currently buffered events, and starts the next batch
+  // internally.
+  void WriteAndReset(protos::pbzero::FtraceEventBundle* bundle);
+
+ private:
+  // First timestamp in a bundle is absolute. The rest are all delta-encoded,
+  // each relative to the preceding sched_switch timestamp.
+  uint64_t last_switch_timestamp_ = 0;
+
+  protozero::StackAllocated<protozero::PackedVarIntBuffer, kMaxElements>
+      switch_timestamp_;
+  protozero::StackAllocated<protozero::PackedVarIntBuffer, kMaxElements>
+      switch_prev_state_;
+  protozero::StackAllocated<protozero::PackedVarIntBuffer, kMaxElements>
+      switch_next_pid_;
+  protozero::StackAllocated<protozero::PackedVarIntBuffer, kMaxElements>
+      switch_next_prio_;
+
+  // Storage for interned strings (without null bytes).
+  char intern_buf_[kMaxElements * (kExpectedCommLength - 1)];
+  size_t intern_buf_write_pos_ = 0;
+
+  // Views into unique interned next_comm strings. Even if every sched_switch
+  // carries a unique next_comm, the ftrace reader is expected to flush the
+  // compact buffer way before this reaches capacity. This is since the cost of
+  // processing each event grows with every unique interned next_comm (as the
+  // interning needs to search all existing internings).
+  std::array<base::StringView, kMaxElements> interned_switch_comms_;
+  uint32_t interned_switch_comms_size_ = 0;
+
+  // One entry per sched_switch event, contains the index of the interned
+  // next_comm string view (i.e. array index into |interned_switch_comms|).
+  protozero::StackAllocated<protozero::PackedVarIntBuffer, kMaxElements>
+      switch_next_comm_index_;
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACED_PROBES_FTRACE_COMPACT_SCHED_H_
diff --git a/src/traced/probes/ftrace/cpu_reader.cc b/src/traced/probes/ftrace/cpu_reader.cc
index e512788..2ac2b09 100644
--- a/src/traced/probes/ftrace/cpu_reader.cc
+++ b/src/traced/probes/ftrace/cpu_reader.cc
@@ -17,11 +17,8 @@
 #include "src/traced/probes/ftrace/cpu_reader.h"
 
 #include <signal.h>
-
 #include <dirent.h>
-#include <map>
-#include <queue>
-#include <string>
+
 #include <utility>
 
 #include "perfetto/base/build_config.h"
@@ -29,19 +26,25 @@
 #include "perfetto/ext/base/metatrace.h"
 #include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/utils.h"
-#include "src/traced/probes/ftrace/ftrace_controller.h"
-#include "src/traced/probes/ftrace/ftrace_data_source.h"
-#include "src/traced/probes/ftrace/proto_translation_table.h"
-
+#include "perfetto/ext/tracing/core/trace_writer.h"
 #include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
 #include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
 #include "protos/perfetto/trace/ftrace/generic.pbzero.h"
 #include "protos/perfetto/trace/trace_packet.pbzero.h"
+#include "src/traced/probes/ftrace/ftrace_config_muxer.h"
+#include "src/traced/probes/ftrace/ftrace_controller.h"
+#include "src/traced/probes/ftrace/ftrace_data_source.h"
+#include "src/traced/probes/ftrace/proto_translation_table.h"
 
 namespace perfetto {
-
 namespace {
 
+// If the compact_sched buffer accumulates more unique strings, the reader will
+// flush it to reset the interning state (and make it cheap again).
+// This is not an exact cap, since we check only at tracing page boundaries.
+// TODO(rsavitski): consider making part of compact_sched config.
+constexpr size_t kCompactSchedInternerThreshold = 64;
+
 // For further documentation of these constants see the kernel source:
 // linux/include/linux/ring_buffer.h
 // Some information about the values of these constants are exposed to user
@@ -102,6 +105,29 @@
   return true;
 }
 
+template <typename T>
+T ReadValue(const uint8_t* ptr) {
+  T t;
+  memcpy(&t, reinterpret_cast<const void*>(ptr), sizeof(T));
+  return t;
+}
+
+// Reads a signed ftrace value as an int64_t, sign extending if necessary.
+static int64_t ReadSignedFtraceValue(const uint8_t* ptr,
+                                     FtraceFieldType ftrace_type) {
+  if (ftrace_type == kFtraceInt32) {
+    int32_t value;
+    memcpy(&value, reinterpret_cast<const void*>(ptr), sizeof(value));
+    return int64_t(value);
+  }
+  if (ftrace_type == kFtraceInt64) {
+    int64_t value;
+    memcpy(&value, reinterpret_cast<const void*>(ptr), sizeof(value));
+    return value;
+  }
+  PERFETTO_FATAL("unexpected ftrace type");
+}
+
 bool SetBlocking(int fd, bool is_blocking) {
   int flags = fcntl(fd, F_GETFL, 0);
   flags = (is_blocking) ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
@@ -112,10 +138,10 @@
 
 using protos::pbzero::GenericFtraceEvent;
 
-CpuReader::CpuReader(const ProtoTranslationTable* table,
-                     size_t cpu,
+CpuReader::CpuReader(size_t cpu,
+                     const ProtoTranslationTable* table,
                      base::ScopedFile trace_fd)
-    : table_(table), cpu_(cpu), trace_fd_(std::move(trace_fd)) {
+    : cpu_(cpu), table_(table), trace_fd_(std::move(trace_fd)) {
   PERFETTO_CHECK(trace_fd_);
   PERFETTO_CHECK(SetBlocking(*trace_fd_, false));
 }
@@ -188,8 +214,6 @@
       // there's a concurrent reader requesting less than a page?). Crash if
       // encountering this situation. Kernel source pointer: see usage of
       // |info->read| within |tracing_buffers_read|.
-      // TODO(rsavitski): don't crash, throw away the partial read & pipe
-      // through an error signal.
       if (res == 0) {
         // Very rare, but possible. Stop for now, should recover.
         PERFETTO_DLOG("[cpu%zu]: 0-sized read from ftrace pipe.", cpu_);
@@ -229,29 +253,94 @@
     }
   }  // end of metatrace::FTRACE_CPU_READ_BATCH
 
-  // Parse the pages and write to the trace for of all relevant data
+  // Parse the pages and write to the trace for all relevant data
   // sources.
-  for (size_t i = 0; i < pages_read; i++) {
-    uint8_t* curr_page = parsing_buf + (i * base::kPageSize);
-    for (FtraceDataSource* data_source : started_data_sources) {
-      auto packet = data_source->trace_writer()->NewTracePacket();
-      auto* bundle = packet->set_ftrace_events();
-      auto* metadata = data_source->mutable_metadata();
-      auto* filter = data_source->event_filter();
+  if (pages_read == 0)
+    return pages_read;
 
-      // Note: The fastpath in proto_trace_parser.cc speculates on the fact
-      // that the cpu field is the first field of the proto message. If this
-      // changes, change proto_trace_parser.cc accordingly.
-      bundle->set_cpu(static_cast<uint32_t>(cpu_));
-
-      size_t evt_size = ParsePage(curr_page, filter, bundle, table_, metadata);
-      PERFETTO_DCHECK(evt_size);
-      bundle->set_lost_events(metadata->lost_events);
-    }
+  for (FtraceDataSource* data_source : started_data_sources) {
+    bool success = ProcessPagesForDataSource(
+        data_source->trace_writer(), data_source->mutable_metadata(), cpu_,
+        data_source->parsing_config(), parsing_buf, pages_read, table_);
+    PERFETTO_CHECK(success);
   }
+
   return pages_read;
 }
 
+// static
+bool CpuReader::ProcessPagesForDataSource(
+    TraceWriter* trace_writer,
+    FtraceMetadata* metadata,
+    size_t cpu,
+    const FtraceDataSourceConfig* ds_config,
+    const uint8_t* parsing_buf,
+    const size_t pages_read,
+    const ProtoTranslationTable* table) {
+  // Begin an FtraceEventBundle, and allocate the buffer for compact scheduler
+  // events (which will be unused if the compact option isn't enabled).
+  CompactSchedBundleState compact_sched;
+  auto packet = trace_writer->NewTracePacket();
+  auto* bundle = packet->set_ftrace_events();
+
+  bool compact_sched_enabled = ds_config->compact_sched.enabled;
+
+  // Note: The fastpath in proto_trace_parser.cc speculates on the fact
+  // that the cpu field is the first field of the proto message. If this
+  // changes, change proto_trace_parser.cc accordingly.
+  bundle->set_cpu(static_cast<uint32_t>(cpu));
+
+  for (size_t i = 0; i < pages_read; i++) {
+    const uint8_t* curr_page = parsing_buf + (i * base::kPageSize);
+    const uint8_t* curr_page_end = curr_page + base::kPageSize;
+    const uint8_t* parse_pos = curr_page;
+    base::Optional<PageHeader> page_header =
+        ParsePageHeader(&parse_pos, table->page_header_size_len());
+
+    if (!page_header.has_value() || page_header->size == 0 ||
+        parse_pos >= curr_page_end ||
+        parse_pos + page_header->size > curr_page_end) {
+      PERFETTO_DFATAL("invalid page header");
+      return false;
+    }
+
+    // Start a new bundle if either:
+    // * The page we're about to read indicates that there was a kernel ring
+    //   buffer overrun since our last read from that per-cpu buffer. We have
+    //   a single |lost_events| field per bundle, so start a new packet.
+    // * The compact_sched buffer is holding more unique interned strings than
+    //   a threshold. We need to flush the compact buffer to make the
+    //   interning lookups cheap again.
+    bool interner_past_threshold =
+        compact_sched_enabled && compact_sched.interned_switch_comms_size() >
+                                     kCompactSchedInternerThreshold;
+    if (page_header->lost_events || interner_past_threshold) {
+      if (compact_sched_enabled)
+        compact_sched.WriteAndReset(bundle);
+      packet->Finalize();
+
+      packet = trace_writer->NewTracePacket();
+      bundle = packet->set_ftrace_events();
+      bundle->set_cpu(static_cast<uint32_t>(cpu));
+      if (page_header->lost_events)
+        bundle->set_lost_events(true);
+    }
+
+    size_t evt_size =
+        ParsePagePayload(parse_pos, &page_header.value(), table, ds_config,
+                         &compact_sched, bundle, metadata);
+
+    // TODO(b/140866160): compare against header->size once padding size
+    // off-by-4 is fixed.
+    PERFETTO_DCHECK(evt_size > 0);
+  }
+
+  if (compact_sched_enabled)
+    compact_sched.WriteAndReset(bundle);
+
+  return true;
+}
+
 // A page header consists of:
 // * timestamp: 8 bytes
 // * commit: 8 bytes on 64 bit, 4 bytes on 32 bit kernels
@@ -309,24 +398,16 @@
 // binary ftrace events. See |ParsePageHeader| for the format of the earlier.
 //
 // This method is deliberately static so it can be tested independently.
-size_t CpuReader::ParsePage(const uint8_t* ptr,
-                            const EventFilter* filter,
-                            FtraceEventBundle* bundle,
-                            const ProtoTranslationTable* table,
-                            FtraceMetadata* metadata) {
-  const uint8_t* const start_of_page = ptr;
-  const uint8_t* const end_of_page = ptr + base::kPageSize;
-
-  auto page_header = ParsePageHeader(&ptr, table->page_header_size_len());
-  if (!page_header.has_value())
-    return 0;
-
-  // ParsePageHeader advances |ptr| to point past the end of the header.
-
-  metadata->lost_events = static_cast<uint32_t>(page_header->lost_events);
+size_t CpuReader::ParsePagePayload(
+    const uint8_t* start_of_payload,
+    const PageHeader* page_header,
+    const ProtoTranslationTable* table,
+    const FtraceDataSourceConfig* ds_config,
+    CompactSchedBundleState* compact_sched_buffer,
+    FtraceEventBundle* bundle,
+    FtraceMetadata* metadata) {
+  const uint8_t* ptr = start_of_payload;
   const uint8_t* const end = ptr + page_header->size;
-  if (end > end_of_page)
-    return 0;
 
   uint64_t timestamp = page_header->timestamp;
 
@@ -396,11 +477,29 @@
         uint16_t ftrace_event_id;
         if (!ReadAndAdvance<uint16_t>(&ptr, end, &ftrace_event_id))
           return 0;
-        if (filter->IsEventEnabled(ftrace_event_id)) {
-          protos::pbzero::FtraceEvent* event = bundle->add_event();
-          event->set_timestamp(timestamp);
-          if (!ParseEvent(ftrace_event_id, start, next, table, event, metadata))
-            return 0;
+
+        if (ds_config->event_filter.IsEventEnabled(ftrace_event_id)) {
+          // Special-cased handling of some scheduler events when compact format
+          // is enabled.
+          bool compact_sched_enabled = ds_config->compact_sched.enabled;
+          const CompactSchedSwitchFormat& sched_switch_format =
+              table->compact_sched_format().sched_switch;
+
+          if (compact_sched_enabled &&
+              ftrace_event_id == sched_switch_format.event_id) {
+            if (event_size < sched_switch_format.size)
+              return 0;
+
+            ParseSchedSwitchCompact(start, timestamp, &sched_switch_format,
+                                    compact_sched_buffer, metadata);
+          } else {
+            // Parse all other types of enabled events.
+            protos::pbzero::FtraceEvent* event = bundle->add_event();
+            event->set_timestamp(timestamp);
+            if (!ParseEvent(ftrace_event_id, start, next, table, event,
+                            metadata))
+              return 0;
+          }
         }
 
         // Jump to next event.
@@ -408,7 +507,7 @@
       }
     }
   }
-  return static_cast<size_t>(ptr - start_of_page);
+  return static_cast<size_t>(ptr - start_of_payload);
 }
 
 // |start| is the start of the current event.
@@ -440,7 +539,8 @@
       message->BeginNestedMessage<protozero::Message>(info.proto_field_id);
 
   // Parse generic event.
-  if (info.proto_field_id == protos::pbzero::FtraceEvent::kGenericFieldNumber) {
+  if (PERFETTO_UNLIKELY(info.proto_field_id ==
+                        protos::pbzero::FtraceEvent::kGenericFieldNumber)) {
     nested->AppendString(GenericFtraceEvent::kEventNameFieldNumber, info.name);
     for (const Field& field : info.fields) {
       auto generic_field = nested->BeginNestedMessage<protozero::Message>(
@@ -556,4 +656,36 @@
   PERFETTO_FATAL("Not reached");  // For gcc
 }
 
+// Parse a sched_switch event according to pre-validated format, and buffer the
+// individual fields in the current compact batch. See the code populating
+// |CompactSchedSwitchFormat| for the assumptions made around the format, which
+// this code is closely tied to.
+// static
+void CpuReader::ParseSchedSwitchCompact(
+    const uint8_t* start,
+    uint64_t timestamp,
+    const CompactSchedSwitchFormat* format,
+    CompactSchedBundleState* compact_sched_buffer,
+    FtraceMetadata* metadata) {
+  compact_sched_buffer->AppendSwitchTimestamp(timestamp);
+
+  int32_t next_pid = ReadValue<int32_t>(start + format->next_pid_offset);
+  compact_sched_buffer->switch_next_pid()->Append(next_pid);
+  metadata->AddPid(next_pid);
+
+  int32_t next_prio = ReadValue<int32_t>(start + format->next_prio_offset);
+  compact_sched_buffer->switch_next_prio()->Append(next_prio);
+
+  // Varint encoding of int32 and int64 is the same, so treat the value as
+  // int64 after reading.
+  int64_t prev_state = ReadSignedFtraceValue(start + format->prev_state_offset,
+                                             format->prev_state_type);
+  compact_sched_buffer->switch_prev_state()->Append(prev_state);
+
+  // next_comm
+  const char* comm_ptr =
+      reinterpret_cast<const char*>(start + format->next_comm_offset);
+  compact_sched_buffer->InternSwitchNextComm(comm_ptr);
+}
+
 }  // namespace perfetto
diff --git a/src/traced/probes/ftrace/cpu_reader.h b/src/traced/probes/ftrace/cpu_reader.h
index 3fe3f47..139eebe 100644
--- a/src/traced/probes/ftrace/cpu_reader.h
+++ b/src/traced/probes/ftrace/cpu_reader.h
@@ -32,8 +32,10 @@
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/base/thread_checker.h"
 #include "perfetto/ext/traced/data_source_types.h"
+#include "perfetto/ext/tracing/core/trace_writer.h"
 #include "perfetto/protozero/message.h"
 #include "perfetto/protozero/message_handle.h"
+#include "src/traced/probes/ftrace/compact_sched.h"
 #include "src/traced/probes/ftrace/ftrace_metadata.h"
 #include "src/traced/probes/ftrace/proto_translation_table.h"
 
@@ -41,6 +43,7 @@
 
 class FtraceDataSource;
 class ProtoTranslationTable;
+struct FtraceDataSourceConfig;
 
 namespace protos {
 namespace pbzero {
@@ -60,8 +63,8 @@
     bool lost_events;
   };
 
-  CpuReader(const ProtoTranslationTable* table,
-            size_t cpu,
+  CpuReader(size_t cpu,
+            const ProtoTranslationTable* table,
             base::ScopedFile trace_fd);
   ~CpuReader();
 
@@ -154,17 +157,21 @@
       const uint8_t** ptr,
       uint16_t page_header_size_len);
 
-  // Parse a raw ftrace page beginning at ptr and write the events a protos
-  // into the provided bundle respecting the given event filter.
+  // Parse the payload of a raw ftrace page, and write the events as protos
+  // into the provided bundle (and/or compact buffer).
   // |table| contains the mix of compile time (e.g. proto field ids) and
   // run time (e.g. field offset and size) information necessary to do this.
   // The table is initialized once at start time by the ftrace controller
   // which passes it to the CpuReader which passes it here.
-  static size_t ParsePage(const uint8_t* ptr,
-                          const EventFilter*,
-                          protos::pbzero::FtraceEventBundle*,
-                          const ProtoTranslationTable* table,
-                          FtraceMetadata*);
+  // The caller is responsible for validating that the page_header->size stays
+  // within the current page.
+  static size_t ParsePagePayload(const uint8_t* start_of_payload,
+                                 const PageHeader* page_header,
+                                 const ProtoTranslationTable* table,
+                                 const FtraceDataSourceConfig* ds_config,
+                                 CompactSchedBundleState* compact_sched_buffer,
+                                 FtraceEventBundle* bundle,
+                                 FtraceMetadata* metadata);
 
   // Parse a single raw ftrace event beginning at |start| and ending at |end|
   // and write it into the provided bundle as a proto.
@@ -186,6 +193,26 @@
                          protozero::Message* message,
                          FtraceMetadata* metadata);
 
+  // Parse a sched_switch event according to pre-validated format, and buffer
+  // the individual fields in the given compact encoding batch.
+  static void ParseSchedSwitchCompact(const uint8_t* start,
+                                      uint64_t timestamp,
+                                      const CompactSchedSwitchFormat* format,
+                                      CompactSchedBundleState* bundle_state,
+                                      FtraceMetadata* metadata);
+
+  // Parses & encodes the given range of contiguous tracing pages. Called by
+  // |ReadAndProcessBatch| for each active data source.
+  //
+  // public and static for testing
+  static bool ProcessPagesForDataSource(TraceWriter* trace_writer,
+                                        FtraceMetadata* metadata,
+                                        size_t cpu,
+                                        const FtraceDataSourceConfig* ds_config,
+                                        const uint8_t* parsing_buf,
+                                        const size_t pages_read,
+                                        const ProtoTranslationTable* table);
+
  private:
   CpuReader(const CpuReader&) = delete;
   CpuReader& operator=(const CpuReader&) = delete;
@@ -200,8 +227,8 @@
       bool first_batch_in_cycle,
       const std::set<FtraceDataSource*>& started_data_sources);
 
-  const ProtoTranslationTable* const table_;
   const size_t cpu_;
+  const ProtoTranslationTable* const table_;
   base::ScopedFile trace_fd_;
 };
 
diff --git a/src/traced/probes/ftrace/cpu_reader_benchmark.cc b/src/traced/probes/ftrace/cpu_reader_benchmark.cc
index 9370a6c..b4d942f 100644
--- a/src/traced/probes/ftrace/cpu_reader_benchmark.cc
+++ b/src/traced/probes/ftrace/cpu_reader_benchmark.cc
@@ -19,6 +19,7 @@
 #include "perfetto/protozero/scattered_stream_writer.h"
 #include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
 #include "src/traced/probes/ftrace/cpu_reader.h"
+#include "src/traced/probes/ftrace/ftrace_config_muxer.h"
 #include "src/traced/probes/ftrace/proto_translation_table.h"
 #include "src/traced/probes/ftrace/test/cpu_reader_support.h"
 
@@ -288,9 +289,12 @@
 
 }  // namespace
 
+using perfetto::CompactSchedBundleState;
 using perfetto::CpuReader;
+using perfetto::DisabledCompactSchedConfigForTesting;
 using perfetto::EventFilter;
 using perfetto::ExamplePage;
+using perfetto::FtraceDataSourceConfig;
 using perfetto::FtraceMetadata;
 using perfetto::GetTable;
 using perfetto::GroupAndName;
@@ -300,6 +304,7 @@
 using protozero::ScatteredStreamWriter;
 using protozero::ScatteredStreamWriterNullDelegate;
 
+// Benchmark for the core logic of the ftrace binary format decoding.
 static void BM_ParsePageFullOfSchedSwitch(benchmark::State& state) {
   const ExamplePage* test_case = &g_full_page_sched_switch;
 
@@ -310,14 +315,27 @@
   ProtoTranslationTable* table = GetTable(test_case->name);
   auto page = PageFromXxd(test_case->data);
 
-  EventFilter filter;
-  filter.AddEnabledEvent(
+  FtraceDataSourceConfig ds_config{EventFilter{},
+                                   DisabledCompactSchedConfigForTesting()};
+  ds_config.event_filter.AddEnabledEvent(
       table->EventToFtraceId(GroupAndName("sched", "sched_switch")));
 
   FtraceMetadata metadata{};
   while (state.KeepRunning()) {
     writer.Reset(&stream);
-    CpuReader::ParsePage(page.get(), &filter, &writer, table, &metadata);
+
+    CompactSchedBundleState compact_buffer;
+    const uint8_t* parse_pos = page.get();
+    perfetto::base::Optional<CpuReader::PageHeader> page_header =
+        CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
+
+    if (!page_header.has_value())
+      return;
+
+    CpuReader::ParsePagePayload(parse_pos, &page_header.value(), table,
+                                &ds_config, &compact_buffer, &writer,
+                                &metadata);
+
     metadata.Clear();
   }
 }
diff --git a/src/traced/probes/ftrace/cpu_reader_fuzzer.cc b/src/traced/probes/ftrace/cpu_reader_fuzzer.cc
index 8a8aedf..61d5b80 100644
--- a/src/traced/probes/ftrace/cpu_reader_fuzzer.cc
+++ b/src/traced/probes/ftrace/cpu_reader_fuzzer.cc
@@ -25,7 +25,9 @@
 #include "perfetto/protozero/scattered_stream_writer.h"
 #include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
 #include "src/traced/probes/ftrace/cpu_reader.h"
+#include "src/traced/probes/ftrace/ftrace_config_muxer.h"
 #include "src/traced/probes/ftrace/test/cpu_reader_support.h"
+#include "src/tracing/core/null_trace_writer.h"
 
 namespace perfetto {
 namespace {
@@ -38,11 +40,8 @@
 
 void FuzzCpuReaderParsePage(const uint8_t* data, size_t size);
 
-void FuzzCpuReaderParsePage(const uint8_t* data, size_t size) {
-  protozero::ScatteredStreamWriterNullDelegate delegate(base::kPageSize);
-  protozero::ScatteredStreamWriter stream(&delegate);
-  FtraceEventBundle writer;
-
+// TODO(rsavitski): make the fuzzer generate multi-page payloads.
+void FuzzCpuReaderProcessPagesForDataSource(const uint8_t* data, size_t size) {
   ProtoTranslationTable* table = GetTable("synthetic");
   if (!table) {
     PERFETTO_FATAL(
@@ -52,15 +51,18 @@
   memset(g_page, 0, base::kPageSize);
   memcpy(g_page, data, std::min(base::kPageSize, size));
 
-  EventFilter filter;
-  filter.AddEnabledEvent(
+  FtraceMetadata metadata{};
+  FtraceDataSourceConfig ds_config{EventFilter{},
+                                   DisabledCompactSchedConfigForTesting()};
+  ds_config.event_filter.AddEnabledEvent(
       table->EventToFtraceId(GroupAndName("sched", "sched_switch")));
-  filter.AddEnabledEvent(
+  ds_config.event_filter.AddEnabledEvent(
       table->EventToFtraceId(GroupAndName("ftrace", "print")));
 
-  writer.Reset(&stream);
-  FtraceMetadata metadata{};
-  CpuReader::ParsePage(g_page, &filter, &writer, table, &metadata);
+  NullTraceWriter null_writer;
+  CpuReader::ProcessPagesForDataSource(&null_writer, &metadata, /*cpu=*/0,
+                                       &ds_config, g_page, /*pages_read=*/1,
+                                       table);
 }
 
 }  // namespace perfetto
@@ -68,6 +70,6 @@
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  perfetto::FuzzCpuReaderParsePage(data, size);
+  perfetto::FuzzCpuReaderProcessPagesForDataSource(data, size);
   return 0;
 }
diff --git a/src/traced/probes/ftrace/cpu_reader_unittest.cc b/src/traced/probes/ftrace/cpu_reader_unittest.cc
index 673b797..d008744 100644
--- a/src/traced/probes/ftrace/cpu_reader_unittest.cc
+++ b/src/traced/probes/ftrace/cpu_reader_unittest.cc
@@ -16,6 +16,7 @@
 
 #include "src/traced/probes/ftrace/cpu_reader.h"
 
+#include <string.h>
 #include <sys/stat.h>
 
 #include "perfetto/base/build_config.h"
@@ -23,18 +24,19 @@
 #include "perfetto/protozero/proto_utils.h"
 #include "perfetto/protozero/scattered_heap_buffer.h"
 #include "perfetto/protozero/scattered_stream_writer.h"
-#include "src/traced/probes/ftrace/event_info.h"
-#include "src/traced/probes/ftrace/proto_translation_table.h"
-#include "test/gtest_and_gmock.h"
-
 #include "protos/perfetto/trace/ftrace/ftrace_event.pb.h"
 #include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
 #include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pb.h"
 #include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
+#include "src/traced/probes/ftrace/event_info.h"
+#include "src/traced/probes/ftrace/ftrace_config_muxer.h"
 #include "src/traced/probes/ftrace/ftrace_procfs.h"
+#include "src/traced/probes/ftrace/proto_translation_table.h"
 #include "src/traced/probes/ftrace/test/cpu_reader_support.h"
 #include "src/traced/probes/ftrace/test/test_messages.pb.h"
 #include "src/traced/probes/ftrace/test/test_messages.pbzero.h"
+#include "src/tracing/core/trace_writer_for_testing.h"
+#include "test/gtest_and_gmock.h"
 
 using protozero::proto_utils::ProtoSchemaType;
 using testing::_;
@@ -116,8 +118,10 @@
   std::unique_ptr<ProtoT> ParseProto() {
     auto bundle = std::unique_ptr<ProtoT>(new ProtoT());
     std::vector<uint8_t> buffer = delegate_.StitchSlices();
-    if (!bundle->ParseFromArray(buffer.data(), static_cast<int>(buffer.size())))
+    if (!bundle->ParseFromArray(buffer.data(),
+                                static_cast<int>(buffer.size()))) {
       return nullptr;
+    }
     return bundle;
   }
 
@@ -371,18 +375,32 @@
   ProtoTranslationTable* table = GetTable(test_case->name);
   auto page = PageFromXxd(test_case->data);
 
-  EventFilter filter;
-  filter.AddEnabledEvent(
+  FtraceDataSourceConfig ds_config{EventFilter{},
+                                   DisabledCompactSchedConfigForTesting()};
+  ds_config.event_filter.AddEnabledEvent(
       table->EventToFtraceId(GroupAndName("ftrace", "print")));
 
   FtraceMetadata metadata{};
-  size_t bytes = CpuReader::ParsePage(
-      page.get(), &filter, bundle_provider.writer(), table, &metadata);
-  EXPECT_EQ(bytes, 60ul);
+  CompactSchedBundleState compact_buffer;
+  const uint8_t* parse_pos = page.get();
+  base::Optional<CpuReader::PageHeader> page_header =
+      CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
+
+  const uint8_t* page_end = page.get() + base::kPageSize;
+  ASSERT_TRUE(page_header.has_value());
+  EXPECT_EQ(44ul, page_header->size);
+  EXPECT_FALSE(page_header->lost_events);
+  EXPECT_TRUE(parse_pos < page_end);
+  EXPECT_TRUE(parse_pos + page_header->size < page_end);
+
+  size_t evt_bytes = CpuReader::ParsePagePayload(
+      parse_pos, &page_header.value(), table, &ds_config, &compact_buffer,
+      bundle_provider.writer(), &metadata);
+
+  EXPECT_EQ(evt_bytes, 44ul);
 
   auto bundle = bundle_provider.ParseProto();
   ASSERT_TRUE(bundle);
-  EXPECT_FALSE(metadata.lost_events);
   ASSERT_EQ(bundle->event().size(), 1);
   const protos::FtraceEvent& event = bundle->event().Get(0);
   EXPECT_EQ(event.pid(), 28712ul);
@@ -486,13 +504,26 @@
   ProtoTranslationTable* table = GetTable(test_case->name);
   auto page = PageFromXxd(test_case->data);
 
-  EventFilter filter;
-  filter.AddEnabledEvent(
+  FtraceDataSourceConfig ds_config{EventFilter{},
+                                   DisabledCompactSchedConfigForTesting()};
+  ds_config.event_filter.AddEnabledEvent(
       table->EventToFtraceId(GroupAndName("ftrace", "print")));
 
   FtraceMetadata metadata{};
-  CpuReader::ParsePage(page.get(), &filter, bundle_provider.writer(), table,
-                       &metadata);
+  CompactSchedBundleState compact_buffer;
+  const uint8_t* parse_pos = page.get();
+  base::Optional<CpuReader::PageHeader> page_header =
+      CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
+
+  const uint8_t* page_end = page.get() + base::kPageSize;
+  ASSERT_TRUE(page_header.has_value());
+  EXPECT_FALSE(page_header->lost_events);
+  EXPECT_TRUE(parse_pos < page_end);
+  EXPECT_TRUE(parse_pos + page_header->size < page_end);
+
+  CpuReader::ParsePagePayload(parse_pos, &page_header.value(), table,
+                              &ds_config, &compact_buffer,
+                              bundle_provider.writer(), &metadata);
 
   auto bundle = bundle_provider.ParseProto();
   ASSERT_TRUE(bundle);
@@ -523,17 +554,31 @@
   ProtoTranslationTable* table = GetTable(test_case->name);
   auto page = PageFromXxd(test_case->data);
 
-  EventFilter filter;
-  filter.AddEnabledEvent(
+  FtraceDataSourceConfig ds_config{EventFilter{},
+                                   DisabledCompactSchedConfigForTesting()};
+  ds_config.event_filter.AddEnabledEvent(
       table->EventToFtraceId(GroupAndName("ftrace", "print")));
 
   FtraceMetadata metadata{};
-  ASSERT_FALSE(CpuReader::ParsePage(
-      page.get(), &filter, bundle_provider.writer(), table, &metadata));
+  CompactSchedBundleState compact_buffer;
+  const uint8_t* parse_pos = page.get();
+  base::Optional<CpuReader::PageHeader> page_header =
+      CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
+
+  const uint8_t* page_end = page.get() + base::kPageSize;
+  ASSERT_TRUE(page_header.has_value());
+  EXPECT_FALSE(page_header->lost_events);
+  EXPECT_TRUE(parse_pos < page_end);
+  EXPECT_TRUE(parse_pos + page_header->size < page_end);
+
+  size_t evt_bytes = CpuReader::ParsePagePayload(
+      parse_pos, &page_header.value(), table, &ds_config, &compact_buffer,
+      bundle_provider.writer(), &metadata);
+
+  ASSERT_EQ(0u, evt_bytes);
 
   auto bundle = bundle_provider.ParseProto();
   ASSERT_TRUE(bundle);
-  EXPECT_FALSE(metadata.lost_events);
   ASSERT_EQ(bundle->event().size(), 1);
   // Although one field is malformed we still see data for the rest
   // since we write the fields as we parse them for speed.
@@ -550,15 +595,26 @@
   ProtoTranslationTable* table = GetTable(test_case->name);
   auto page = PageFromXxd(test_case->data);
 
-  EventFilter filter;
+  FtraceDataSourceConfig ds_config{EventFilter{},
+                                   DisabledCompactSchedConfigForTesting()};
 
   FtraceMetadata metadata{};
-  ASSERT_TRUE(CpuReader::ParsePage(page.get(), &filter,
-                                   bundle_provider.writer(), table, &metadata));
+  CompactSchedBundleState compact_buffer;
+  const uint8_t* parse_pos = page.get();
+  base::Optional<CpuReader::PageHeader> page_header =
+      CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
+
+  ASSERT_TRUE(page_header.has_value());
+  EXPECT_FALSE(page_header->lost_events);
+
+  size_t evt_bytes = CpuReader::ParsePagePayload(
+      parse_pos, &page_header.value(), table, &ds_config, &compact_buffer,
+      bundle_provider.writer(), &metadata);
+
+  EXPECT_LT(0u, evt_bytes);
 
   auto bundle = bundle_provider.ParseProto();
   ASSERT_TRUE(bundle);
-  EXPECT_FALSE(metadata.lost_events);
   ASSERT_EQ(bundle->event().size(), 0);
 }
 
@@ -603,17 +659,31 @@
   ProtoTranslationTable* table = GetTable(test_case->name);
   auto page = PageFromXxd(test_case->data);
 
-  EventFilter filter;
-  filter.AddEnabledEvent(
+  FtraceDataSourceConfig ds_config{EventFilter{},
+                                   DisabledCompactSchedConfigForTesting()};
+  ds_config.event_filter.AddEnabledEvent(
       table->EventToFtraceId(GroupAndName("ftrace", "print")));
 
   FtraceMetadata metadata{};
-  ASSERT_TRUE(CpuReader::ParsePage(page.get(), &filter,
-                                   bundle_provider.writer(), table, &metadata));
+  CompactSchedBundleState compact_buffer;
+  const uint8_t* parse_pos = page.get();
+  base::Optional<CpuReader::PageHeader> page_header =
+      CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
+
+  const uint8_t* page_end = page.get() + base::kPageSize;
+  ASSERT_TRUE(page_header.has_value());
+  EXPECT_FALSE(page_header->lost_events);
+  EXPECT_TRUE(parse_pos < page_end);
+  EXPECT_TRUE(parse_pos + page_header->size < page_end);
+
+  size_t evt_bytes = CpuReader::ParsePagePayload(
+      parse_pos, &page_header.value(), table, &ds_config, &compact_buffer,
+      bundle_provider.writer(), &metadata);
+
+  EXPECT_LT(0u, evt_bytes);
 
   auto bundle = bundle_provider.ParseProto();
   ASSERT_TRUE(bundle);
-  EXPECT_FALSE(metadata.lost_events);
   ASSERT_EQ(bundle->event().size(), 3);
 
   {
@@ -699,17 +769,31 @@
   ProtoTranslationTable* table = GetTable(test_case->name);
   auto page = PageFromXxd(test_case->data);
 
-  EventFilter filter;
-  filter.AddEnabledEvent(
+  FtraceDataSourceConfig ds_config{EventFilter{},
+                                   DisabledCompactSchedConfigForTesting()};
+  ds_config.event_filter.AddEnabledEvent(
       table->EventToFtraceId(GroupAndName("sched", "sched_switch")));
 
   FtraceMetadata metadata{};
-  ASSERT_TRUE(CpuReader::ParsePage(page.get(), &filter,
-                                   bundle_provider.writer(), table, &metadata));
+  CompactSchedBundleState compact_buffer;
+  const uint8_t* parse_pos = page.get();
+  base::Optional<CpuReader::PageHeader> page_header =
+      CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
+
+  const uint8_t* page_end = page.get() + base::kPageSize;
+  ASSERT_TRUE(page_header.has_value());
+  EXPECT_FALSE(page_header->lost_events);
+  EXPECT_TRUE(parse_pos < page_end);
+  EXPECT_TRUE(parse_pos + page_header->size < page_end);
+
+  size_t evt_bytes = CpuReader::ParsePagePayload(
+      parse_pos, &page_header.value(), table, &ds_config, &compact_buffer,
+      bundle_provider.writer(), &metadata);
+
+  EXPECT_LT(0u, evt_bytes);
 
   auto bundle = bundle_provider.ParseProto();
   ASSERT_TRUE(bundle);
-  EXPECT_FALSE(metadata.lost_events);
   ASSERT_EQ(bundle->event().size(), 6);
 
   {
@@ -725,6 +809,72 @@
   }
 }
 
+TEST(CpuReaderTest, ParseSixSchedSwitchCompactFormat) {
+  const ExamplePage* test_case = &g_six_sched_switch;
+
+  BundleProvider bundle_provider(base::kPageSize);
+  ProtoTranslationTable* table = GetTable(test_case->name);
+  auto page = PageFromXxd(test_case->data);
+
+  FtraceDataSourceConfig ds_config{EventFilter{},
+                                   EnabledCompactSchedConfigForTesting()};
+  ds_config.event_filter.AddEnabledEvent(
+      table->EventToFtraceId(GroupAndName("sched", "sched_switch")));
+
+  FtraceMetadata metadata{};
+  CompactSchedBundleState compact_buffer;
+  const uint8_t* parse_pos = page.get();
+  base::Optional<CpuReader::PageHeader> page_header =
+      CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
+
+  const uint8_t* page_end = page.get() + base::kPageSize;
+  ASSERT_TRUE(page_header.has_value());
+  EXPECT_FALSE(page_header->lost_events);
+  EXPECT_TRUE(parse_pos < page_end);
+  EXPECT_TRUE(parse_pos + page_header->size < page_end);
+
+  size_t evt_bytes = CpuReader::ParsePagePayload(
+      parse_pos, &page_header.value(), table, &ds_config, &compact_buffer,
+      bundle_provider.writer(), &metadata);
+
+  EXPECT_LT(0u, evt_bytes);
+
+  // Nothing written into the proto yet:
+  auto bundle = bundle_provider.ParseProto();
+  ASSERT_TRUE(bundle);
+  EXPECT_EQ(0, bundle->event().size());
+  EXPECT_FALSE(bundle->has_compact_sched());
+
+  // Instead, sched switch fields were buffered:
+  EXPECT_LT(0u, compact_buffer.interned_switch_comms_size());
+
+  // Write the buffer out & check the serialized format:
+  compact_buffer.WriteAndReset(bundle_provider.writer());
+  bundle_provider.writer()->Finalize();
+  bundle = bundle_provider.ParseProto();
+  ASSERT_TRUE(bundle);
+
+  const auto& compact_sched = bundle->compact_sched();
+
+  EXPECT_EQ(6, compact_sched.switch_timestamp().size());
+  EXPECT_EQ(6, compact_sched.switch_prev_state().size());
+  EXPECT_EQ(6, compact_sched.switch_next_pid().size());
+  EXPECT_EQ(6, compact_sched.switch_next_prio().size());
+  // 4 unique interned next_comm strings:
+  EXPECT_EQ(4, compact_sched.switch_next_comm_table().size());
+  EXPECT_EQ(6, compact_sched.switch_next_comm_index().size());
+
+  // First event exactly as expected (absolute timestamp):
+  EXPECT_TRUE(
+      WithinOneMicrosecond(compact_sched.switch_timestamp(0), 1045157, 722134));
+  EXPECT_EQ(1, compact_sched.switch_prev_state(0));
+  EXPECT_EQ(3733, compact_sched.switch_next_pid(0));
+  EXPECT_EQ(120, compact_sched.switch_next_prio(0));
+  std::string next_comm = compact_sched.switch_next_comm_table(
+      static_cast<int>(compact_sched.switch_next_comm_index(0)));
+  EXPECT_EQ("sleep", next_comm);
+}
+
 TEST_F(CpuReaderTableTest, ParseAllFields) {
   using FakeEventProvider =
       ProtoProvider<pbzero::FakeFtraceEvent, FakeFtraceEvent>;
@@ -872,7 +1022,8 @@
 
   ProtoTranslationTable table(
       &ftrace_, events, std::move(common_fields),
-      ProtoTranslationTable::DefaultPageHeaderSpecForTesting());
+      ProtoTranslationTable::DefaultPageHeaderSpecForTesting(),
+      InvalidCompactSchedEventFormatForTesting());
 
   FakeEventProvider provider(base::kPageSize);
 
@@ -964,6 +1115,73 @@
   EXPECT_THAT(metadata.pids, Contains(9999));
 }
 
+// Page with a single sched_switch, no data loss.
+static char g_switch_page[] =
+    R"(
+    00000000: 2b16 c3be 90b6 0300 4c00 0000 0000 0000  ................
+    00000010: 1e00 0000 0000 0000 1000 0000 2f00 0103  ................
+    00000020: 0300 0000 6b73 6f66 7469 7271 642f 3000  ................
+    00000030: 0000 0000 0300 0000 7800 0000 0100 0000  ................
+    00000040: 0000 0000 736c 6565 7000 722f 3000 0000  ................
+    00000050: 0000 0000 950e 0000 7800 0000 0000 0000  ................
+    )";
+
+// Page with a single sched_switch, header has data loss flag set.
+static char g_switch_page_lost_events[] =
+    R"(
+    00000000: 2b16 c3be 90b6 0300 4c00 0080 ffff ffff  ................
+    00000010: 1e00 0000 0000 0000 1000 0000 2f00 0103  ................
+    00000020: 0300 0000 6b73 6f66 7469 7271 642f 3000  ................
+    00000030: 0000 0000 0300 0000 7800 0000 0100 0000  ................
+    00000040: 0000 0000 736c 6565 7000 722f 3000 0000  ................
+    00000050: 0000 0000 950e 0000 7800 0000 0000 0000  ................
+    )";
+
+TEST(CpuReaderTest, NewPacketOnLostEvents) {
+  auto page_ok = PageFromXxd(g_switch_page);
+  auto page_loss = PageFromXxd(g_switch_page_lost_events);
+
+  std::vector<const void*> test_page_order = {
+      page_ok.get(),   page_ok.get(), page_ok.get(), page_loss.get(),
+      page_loss.get(), page_ok.get(), page_ok.get(), page_ok.get()};
+
+  // Prepare a buffer with 8 contiguous pages, with the above contents.
+  static constexpr size_t kTestPages = 8;
+  uint8_t buf[base::kPageSize * kTestPages] = {};
+  for (size_t i = 0; i < kTestPages; i++) {
+    void* dest = buf + (i * base::kPageSize);
+    memcpy(dest, static_cast<const void*>(test_page_order[i]), base::kPageSize);
+  }
+
+  BundleProvider bundle_provider(base::kPageSize);
+  ProtoTranslationTable* table = GetTable("synthetic");
+  FtraceMetadata metadata{};
+  FtraceDataSourceConfig ds_config{EventFilter{},
+                                   DisabledCompactSchedConfigForTesting()};
+  ds_config.event_filter.AddEnabledEvent(
+      table->EventToFtraceId(GroupAndName("sched", "sched_switch")));
+
+  TraceWriterForTesting trace_writer;
+  CpuReader::ProcessPagesForDataSource(&trace_writer, &metadata, /*cpu=*/1,
+                                       &ds_config, buf, kTestPages, table);
+
+  // Each packet should contain the parsed contents of a contiguous run of pages
+  // without data loss.
+  // So we should get three packets (each page has 1 event):
+  //   [3 events] [1 event] [4 events].
+  std::vector<protos::TracePacket> packets = trace_writer.GetAllTracePackets();
+
+  ASSERT_EQ(3u, packets.size());
+  EXPECT_FALSE(packets[0].ftrace_events().lost_events());
+  EXPECT_EQ(3, packets[0].ftrace_events().event().size());
+
+  EXPECT_TRUE(packets[1].ftrace_events().lost_events());
+  EXPECT_EQ(1, packets[1].ftrace_events().event().size());
+
+  EXPECT_TRUE(packets[2].ftrace_events().lost_events());
+  EXPECT_EQ(4, packets[2].ftrace_events().event().size());
+}
+
 TEST(CpuReaderTest, TranslateBlockDeviceIDToUserspace) {
   const uint32_t kKernelBlockDeviceId = 271581216;
   const BlockDeviceID kUserspaceBlockDeviceId = 66336;
@@ -1396,17 +1614,31 @@
   ProtoTranslationTable* table = GetTable(test_case->name);
   auto page = PageFromXxd(test_case->data);
 
-  EventFilter filter;
-  filter.AddEnabledEvent(
+  FtraceDataSourceConfig ds_config{EventFilter{},
+                                   DisabledCompactSchedConfigForTesting()};
+  ds_config.event_filter.AddEnabledEvent(
       table->EventToFtraceId(GroupAndName("sched", "sched_switch")));
 
   FtraceMetadata metadata{};
-  ASSERT_TRUE(CpuReader::ParsePage(page.get(), &filter,
-                                   bundle_provider.writer(), table, &metadata));
+  CompactSchedBundleState compact_buffer;
+  const uint8_t* parse_pos = page.get();
+  base::Optional<CpuReader::PageHeader> page_header =
+      CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
+
+  const uint8_t* page_end = page.get() + base::kPageSize;
+  ASSERT_TRUE(page_header.has_value());
+  EXPECT_FALSE(page_header->lost_events);
+  EXPECT_TRUE(parse_pos < page_end);
+  EXPECT_TRUE(parse_pos + page_header->size < page_end);
+
+  size_t evt_bytes = CpuReader::ParsePagePayload(
+      parse_pos, &page_header.value(), table, &ds_config, &compact_buffer,
+      bundle_provider.writer(), &metadata);
+
+  EXPECT_LT(0u, evt_bytes);
 
   auto bundle = bundle_provider.ParseProto();
   ASSERT_TRUE(bundle);
-  EXPECT_FALSE(metadata.lost_events);
   EXPECT_EQ(bundle->event().size(), 59);
 }
 
@@ -1827,17 +2059,31 @@
   ProtoTranslationTable* table = GetTable(test_case->name);
   auto page = PageFromXxd(test_case->data);
 
-  EventFilter filter;
-  filter.AddEnabledEvent(
+  FtraceDataSourceConfig ds_config{EventFilter{},
+                                   DisabledCompactSchedConfigForTesting()};
+  ds_config.event_filter.AddEnabledEvent(
       table->EventToFtraceId(GroupAndName("sched", "sched_switch")));
 
   FtraceMetadata metadata{};
-  ASSERT_TRUE(CpuReader::ParsePage(page.get(), &filter,
-                                   bundle_provider.writer(), table, &metadata));
+  CompactSchedBundleState compact_buffer;
+  const uint8_t* parse_pos = page.get();
+  base::Optional<CpuReader::PageHeader> page_header =
+      CpuReader::ParsePageHeader(&parse_pos, table->page_header_size_len());
+
+  const uint8_t* page_end = page.get() + base::kPageSize;
+  ASSERT_TRUE(page_header.has_value());
+  EXPECT_TRUE(page_header->lost_events);  // data loss
+  EXPECT_TRUE(parse_pos < page_end);
+  EXPECT_TRUE(parse_pos + page_header->size < page_end);
+
+  size_t evt_bytes = CpuReader::ParsePagePayload(
+      parse_pos, &page_header.value(), table, &ds_config, &compact_buffer,
+      bundle_provider.writer(), &metadata);
+
+  EXPECT_LT(0u, evt_bytes);
 
   auto bundle = bundle_provider.ParseProto();
   ASSERT_TRUE(bundle);
-  EXPECT_TRUE(metadata.lost_events);
 }
 
 }  // namespace perfetto
diff --git a/src/traced/probes/ftrace/ftrace_config.cc b/src/traced/probes/ftrace/ftrace_config.cc
index 7c7fe46..92bc28a 100644
--- a/src/traced/probes/ftrace/ftrace_config.cc
+++ b/src/traced/probes/ftrace/ftrace_config.cc
@@ -45,7 +45,8 @@
          (atrace_categories_ == other.atrace_categories_) &&
          (atrace_apps_ == other.atrace_apps_) &&
          (buffer_size_kb_ == other.buffer_size_kb_) &&
-         (drain_period_ms_ == other.drain_period_ms_);
+         (drain_period_ms_ == other.drain_period_ms_) &&
+         (compact_sched_ == other.compact_sched_);
 }
 #pragma GCC diagnostic pop
 
@@ -94,6 +95,8 @@
                 "size mismatch");
   drain_period_ms_ =
       static_cast<decltype(drain_period_ms_)>(proto.drain_period_ms());
+
+  compact_sched_->FromProto(proto.compact_sched());
   unknown_fields_ = proto.unknown_fields();
 }
 
@@ -128,6 +131,49 @@
                 "size mismatch");
   proto->set_drain_period_ms(
       static_cast<decltype(proto->drain_period_ms())>(drain_period_ms_));
+
+  compact_sched_->ToProto(proto->mutable_compact_sched());
+  *(proto->mutable_unknown_fields()) = unknown_fields_;
+}
+
+FtraceConfig::CompactSchedConfig::CompactSchedConfig() = default;
+FtraceConfig::CompactSchedConfig::~CompactSchedConfig() = default;
+FtraceConfig::CompactSchedConfig::CompactSchedConfig(
+    const FtraceConfig::CompactSchedConfig&) = default;
+FtraceConfig::CompactSchedConfig& FtraceConfig::CompactSchedConfig::operator=(
+    const FtraceConfig::CompactSchedConfig&) = default;
+FtraceConfig::CompactSchedConfig::CompactSchedConfig(
+    FtraceConfig::CompactSchedConfig&&) noexcept = default;
+FtraceConfig::CompactSchedConfig& FtraceConfig::CompactSchedConfig::operator=(
+    FtraceConfig::CompactSchedConfig&&) = default;
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+bool FtraceConfig::CompactSchedConfig::operator==(
+    const FtraceConfig::CompactSchedConfig& other) const {
+  return (enabled_ == other.enabled_);
+}
+#pragma GCC diagnostic pop
+
+void FtraceConfig::CompactSchedConfig::ParseRawProto(const std::string& raw) {
+  perfetto::protos::FtraceConfig_CompactSchedConfig proto;
+  proto.ParseFromString(raw);
+  FromProto(proto);
+}
+
+void FtraceConfig::CompactSchedConfig::FromProto(
+    const perfetto::protos::FtraceConfig_CompactSchedConfig& proto) {
+  static_assert(sizeof(enabled_) == sizeof(proto.enabled()), "size mismatch");
+  enabled_ = static_cast<decltype(enabled_)>(proto.enabled());
+  unknown_fields_ = proto.unknown_fields();
+}
+
+void FtraceConfig::CompactSchedConfig::ToProto(
+    perfetto::protos::FtraceConfig_CompactSchedConfig* proto) const {
+  proto->Clear();
+
+  static_assert(sizeof(enabled_) == sizeof(proto->enabled()), "size mismatch");
+  proto->set_enabled(static_cast<decltype(proto->enabled())>(enabled_));
   *(proto->mutable_unknown_fields()) = unknown_fields_;
 }
 
diff --git a/src/traced/probes/ftrace/ftrace_config.h b/src/traced/probes/ftrace/ftrace_config.h
index 2de3e67..0567cc3 100644
--- a/src/traced/probes/ftrace/ftrace_config.h
+++ b/src/traced/probes/ftrace/ftrace_config.h
@@ -40,7 +40,8 @@
 namespace perfetto {
 namespace protos {
 class FtraceConfig;
-}
+class FtraceConfig_CompactSchedConfig;
+}  // namespace protos
 }  // namespace perfetto
 
 namespace perfetto {
@@ -48,6 +49,36 @@
 
 class PERFETTO_EXPORT FtraceConfig {
  public:
+  class PERFETTO_EXPORT CompactSchedConfig {
+   public:
+    CompactSchedConfig();
+    ~CompactSchedConfig();
+    CompactSchedConfig(CompactSchedConfig&&) noexcept;
+    CompactSchedConfig& operator=(CompactSchedConfig&&);
+    CompactSchedConfig(const CompactSchedConfig&);
+    CompactSchedConfig& operator=(const CompactSchedConfig&);
+    bool operator==(const CompactSchedConfig&) const;
+    bool operator!=(const CompactSchedConfig& other) const {
+      return !(*this == other);
+    }
+
+    // Raw proto decoding.
+    void ParseRawProto(const std::string&);
+    // Conversion methods from/to the corresponding protobuf types.
+    void FromProto(const perfetto::protos::FtraceConfig_CompactSchedConfig&);
+    void ToProto(perfetto::protos::FtraceConfig_CompactSchedConfig*) const;
+
+    bool enabled() const { return enabled_; }
+    void set_enabled(bool value) { enabled_ = value; }
+
+   private:
+    bool enabled_{};
+
+    // Allows to preserve unknown protobuf fields for compatibility
+    // with future versions of .proto files.
+    std::string unknown_fields_;
+  };
+
   FtraceConfig();
   ~FtraceConfig();
   FtraceConfig(FtraceConfig&&) noexcept;
@@ -106,12 +137,16 @@
   uint32_t drain_period_ms() const { return drain_period_ms_; }
   void set_drain_period_ms(uint32_t value) { drain_period_ms_ = value; }
 
+  const CompactSchedConfig& compact_sched() const { return *compact_sched_; }
+  CompactSchedConfig* mutable_compact_sched() { return compact_sched_.get(); }
+
  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_{};
+  ::perfetto::base::CopyablePtr<CompactSchedConfig> compact_sched_;
 
   // Allows to preserve unknown protobuf fields for compatibility
   // with future versions of .proto files.
diff --git a/src/traced/probes/ftrace/ftrace_config_muxer.cc b/src/traced/probes/ftrace/ftrace_config_muxer.cc
index fe8c291..cc97bf2 100644
--- a/src/traced/probes/ftrace/ftrace_config_muxer.cc
+++ b/src/traced/probes/ftrace/ftrace_config_muxer.cc
@@ -24,7 +24,9 @@
 #include <algorithm>
 
 #include "perfetto/ext/base/utils.h"
+#include "protos/perfetto/trace/ftrace/sched.pbzero.h"
 #include "src/traced/probes/ftrace/atrace_wrapper.h"
+#include "src/traced/probes/ftrace/compact_sched.h"
 
 namespace perfetto {
 namespace {
@@ -392,19 +394,15 @@
 
 FtraceConfigMuxer::FtraceConfigMuxer(FtraceProcfs* ftrace,
                                      ProtoTranslationTable* table)
-    : ftrace_(ftrace),
-      table_(table),
-      current_state_(),
-      filters_(),
-      configs_() {}
+    : ftrace_(ftrace), table_(table), current_state_(), ds_configs_() {}
 FtraceConfigMuxer::~FtraceConfigMuxer() = default;
 
 FtraceConfigId FtraceConfigMuxer::SetupConfig(const FtraceConfig& request) {
   EventFilter filter;
-  FtraceConfig actual;
   bool is_ftrace_enabled = ftrace_->IsTracingEnabled();
-  if (configs_.empty()) {
+  if (ds_configs_.empty()) {
     PERFETTO_DCHECK(active_configs_.empty());
+
     PERFETTO_DCHECK(!current_state_.tracing_on);
 
     // If someone outside of perfetto is using ftrace give up now.
@@ -433,29 +431,35 @@
                     group_and_name.ToString().c_str());
       continue;
     }
+    // Note: ftrace events are always implicitly enabled (and don't have an
+    // "enable" file). So they aren't tracked by the central event filter (but
+    // still need to be added to the per data source event filter to retain the
+    // events during parsing).
     if (current_state_.ftrace_events.IsEventEnabled(event->ftrace_event_id) ||
         std::string("ftrace") == event->group) {
       filter.AddEnabledEvent(event->ftrace_event_id);
-      *actual.add_ftrace_events() = group_and_name.ToString();
       continue;
     }
     if (ftrace_->EnableEvent(event->group, event->name)) {
       current_state_.ftrace_events.AddEnabledEvent(event->ftrace_event_id);
       filter.AddEnabledEvent(event->ftrace_event_id);
-      *actual.add_ftrace_events() = group_and_name.ToString();
     } else {
       PERFETTO_DPLOG("Failed to enable %s.", group_and_name.ToString().c_str());
     }
   }
 
+  auto compact_sched =
+      CreateCompactSchedConfig(request, table_->compact_sched_format());
+
   FtraceConfigId id = ++last_id_;
-  configs_.emplace(id, std::move(actual));
-  filters_.emplace(id, std::move(filter));
+  ds_configs_.emplace(std::piecewise_construct, std::forward_as_tuple(id),
+                      std::forward_as_tuple(std::move(filter), compact_sched));
+
   return id;
 }
 
 bool FtraceConfigMuxer::ActivateConfig(FtraceConfigId id) {
-  if (!id || configs_.count(id) == 0) {
+  if (!id || ds_configs_.count(id) == 0) {
     PERFETTO_DFATAL("Config not found");
     return false;
   }
@@ -478,11 +482,11 @@
 }
 
 bool FtraceConfigMuxer::RemoveConfig(FtraceConfigId config_id) {
-  if (!config_id || !filters_.erase(config_id) || !configs_.erase(config_id))
+  if (!config_id || !ds_configs_.erase(config_id))
     return false;
   EventFilter expected_ftrace_events;
-  for (const auto& id_filter : filters_) {
-    expected_ftrace_events.EnableEventsFrom(id_filter.second);
+  for (const auto& ds_config : ds_configs_) {
+    expected_ftrace_events.EnableEventsFrom(ds_config.second.event_filter);
   }
 
   // Disable any events that are currently enabled, but are not in any configs
@@ -513,7 +517,7 @@
   // Even if we don't have any other active configs, we might still have idle
   // configs around. Tear down the rest of the ftrace config only if all
   // configs are removed.
-  if (configs_.empty()) {
+  if (ds_configs_.empty()) {
     if (ftrace_->SetCpuBufferSizeInPages(1))
       current_state_.cpu_buffer_size_pages = 1;
     ftrace_->DisableAllEvents();
@@ -525,16 +529,11 @@
   return true;
 }
 
-const FtraceConfig* FtraceConfigMuxer::GetConfigForTesting(FtraceConfigId id) {
-  if (!configs_.count(id))
+const FtraceDataSourceConfig* FtraceConfigMuxer::GetDataSourceConfig(
+    FtraceConfigId id) {
+  if (!ds_configs_.count(id))
     return nullptr;
-  return &configs_.at(id);
-}
-
-const EventFilter* FtraceConfigMuxer::GetEventFilter(FtraceConfigId id) {
-  if (!filters_.count(id))
-    return nullptr;
-  return &filters_.at(id);
+  return &ds_configs_.at(id);
 }
 
 void FtraceConfigMuxer::SetupClock(const FtraceConfig&) {
diff --git a/src/traced/probes/ftrace/ftrace_config_muxer.h b/src/traced/probes/ftrace/ftrace_config_muxer.h
index 1f43673..416a38b 100644
--- a/src/traced/probes/ftrace/ftrace_config_muxer.h
+++ b/src/traced/probes/ftrace/ftrace_config_muxer.h
@@ -20,6 +20,7 @@
 #include <map>
 #include <set>
 
+#include "src/traced/probes/ftrace/compact_sched.h"
 #include "src/traced/probes/ftrace/ftrace_config_utils.h"
 #include "src/traced/probes/ftrace/ftrace_controller.h"
 #include "src/traced/probes/ftrace/ftrace_procfs.h"
@@ -27,20 +28,33 @@
 
 namespace perfetto {
 
+// State held by the muxer per data source, used to parse ftrace according to
+// that data source's config.
+struct FtraceDataSourceConfig {
+  FtraceDataSourceConfig(EventFilter _event_filter,
+                         CompactSchedConfig _compact_sched)
+      : event_filter(std::move(_event_filter)), compact_sched(_compact_sched) {}
+
+  // The event filter allows to quickly check if a certain ftrace event with id
+  // x is enabled for this data source.
+  EventFilter event_filter;
+
+  // Configuration of the optional compact encoding of scheduling events.
+  const CompactSchedConfig compact_sched;
+};
+
 // Ftrace is a bunch of globally modifiable persistent state.
 // Given a number of FtraceConfig's we need to find the best union of all
 // the settings to make everyone happy while also watching out for anybody
 // messing with the ftrace settings at the same time as us.
-
+//
 // Specifically FtraceConfigMuxer takes in a *requested* FtraceConfig
 // (|SetupConfig|), makes a best effort attempt to modify the ftrace
 // debugfs files to honor those settings without interrupting other perfetto
 // traces already in progress or other users of ftrace, then returns an
 // FtraceConfigId representing that config or zero on failure.
-
-// To see which settings we actually managed to set you can call |GetConfig|
-// and when you are finished with a config you can signal that with
-// |RemoveConfig|.
+//
+// When you are finished with a config you can signal that with |RemoveConfig|.
 class FtraceConfigMuxer {
  public:
   // The FtraceConfigMuxer and ProtoTranslationTable
@@ -56,7 +70,6 @@
   // (if you enable an atrace category we try to give you the matching events).
   // If someone else is tracing we won't touch atrace (since it resets the
   // buffer).
-  // To see the config you ended up with use |GetConfig|.
   FtraceConfigId SetupConfig(const FtraceConfig& request);
 
   // Activate ftrace for the given config (if not already active).
@@ -66,7 +79,7 @@
   // or already removed.
   bool RemoveConfig(FtraceConfigId);
 
-  const EventFilter* GetEventFilter(FtraceConfigId id);
+  const FtraceDataSourceConfig* GetDataSourceConfig(FtraceConfigId id);
 
   // Returns the current per-cpu buffer size, as configured by this muxer
   // (without consulting debugfs). Constant for a given tracing session.
@@ -79,19 +92,19 @@
     SetupClock(request);
   }
 
-  const FtraceConfig* GetConfigForTesting(FtraceConfigId id);
-
   std::set<GroupAndName> GetFtraceEventsForTesting(
       const FtraceConfig& request,
       const ProtoTranslationTable* table) {
     return GetFtraceEvents(request, table);
   }
 
+  const EventFilter* GetCentralEventFilterForTesting() const {
+    return &current_state_.ftrace_events;
+  }
+
  private:
   struct FtraceState {
     EventFilter ftrace_events;
-    std::set<std::string> atrace_categories;
-    std::set<std::string> atrace_apps;
     bool tracing_on = false;
     bool atrace_on = false;
     size_t cpu_buffer_size_pages = 0;
@@ -120,16 +133,13 @@
 
   FtraceState current_state_;
 
-  // There is a filter per config. These filters allow a quick way
-  // to check if a certain ftrace event with id x is enabled.
-  std::map<FtraceConfigId, EventFilter> filters_;
+  // Set of all requested tracing configurations, with the associated derived
+  // data used during parsing. Note that not all of these configurations might
+  // be active. When a config is present but not active, we do setup buffer
+  // sizes and events, but don't enable ftrace (i.e. tracing_on).
+  std::map<FtraceConfigId, FtraceDataSourceConfig> ds_configs_;
 
-  // Set of all configurations. Note that not all of them might be active.
-  // When a config is present but not active, we do setup buffer sizes and
-  // events, but don't enable ftrace (i.e. tracing_on).
-  std::map<FtraceConfigId, FtraceConfig> configs_;
-
-  // Subset of |configs_| that are currently active. At any time ftrace is
+  // Subset of |ds_configs_| that are currently active. At any time ftrace is
   // enabled iff |active_configs_| is not empty.
   std::set<FtraceConfigId> active_configs_;
 };
diff --git a/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc b/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc
index 2269929..8901cb5 100644
--- a/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc
+++ b/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc
@@ -19,6 +19,7 @@
 #include <memory>
 
 #include "src/traced/probes/ftrace/atrace_wrapper.h"
+#include "src/traced/probes/ftrace/compact_sched.h"
 #include "src/traced/probes/ftrace/ftrace_procfs.h"
 #include "src/traced/probes/ftrace/proto_translation_table.h"
 #include "test/gtest_and_gmock.h"
@@ -33,7 +34,6 @@
 using testing::NiceMock;
 using testing::Not;
 using testing::Return;
-using testing::UnorderedElementsAre;
 
 namespace perfetto {
 namespace {
@@ -78,11 +78,13 @@
   MockProtoTranslationTable(NiceMock<MockFtraceProcfs>* ftrace_procfs,
                             const std::vector<Event>& events,
                             std::vector<Field> common_fields,
-                            FtracePageHeaderSpec ftrace_page_header_spec)
+                            FtracePageHeaderSpec ftrace_page_header_spec,
+                            CompactSchedEventFormat compact_sched_format)
       : ProtoTranslationTable(ftrace_procfs,
                               events,
                               common_fields,
-                              ftrace_page_header_spec) {}
+                              ftrace_page_header_spec,
+                              compact_sched_format) {}
   MOCK_METHOD1(GetOrCreateEvent, Event*(const GroupAndName& group_and_name));
   MOCK_CONST_METHOD1(GetEvent,
                      const Event*(const GroupAndName& group_and_name));
@@ -96,16 +98,24 @@
     return std::unique_ptr<MockProtoTranslationTable>(
         new MockProtoTranslationTable(
             &table_procfs_, events, std::move(common_fields),
-            ProtoTranslationTable::DefaultPageHeaderSpecForTesting()));
+            ProtoTranslationTable::DefaultPageHeaderSpecForTesting(),
+            InvalidCompactSchedEventFormatForTesting()));
   }
-  std::unique_ptr<ProtoTranslationTable> CreateFakeTable() {
+
+  static constexpr int kFakeSchedSwitchEventId = 1;
+  static constexpr int kCgroupMkdirEventId = 12;
+  static constexpr int kFakePrintEventId = 20;
+
+  std::unique_ptr<ProtoTranslationTable> CreateFakeTable(
+      CompactSchedEventFormat compact_format =
+          InvalidCompactSchedEventFormatForTesting()) {
     std::vector<Field> common_fields;
     std::vector<Event> events;
     {
       Event event;
       event.name = "sched_switch";
       event.group = "sched";
-      event.ftrace_event_id = 1;
+      event.ftrace_event_id = kFakeSchedSwitchEventId;
       events.push_back(event);
     }
 
@@ -129,7 +139,7 @@
       Event event;
       event.name = "cgroup_mkdir";
       event.group = "cgroup";
-      event.ftrace_event_id = 12;
+      event.ftrace_event_id = kCgroupMkdirEventId;
       events.push_back(event);
     }
 
@@ -153,13 +163,14 @@
       Event event;
       event.name = "print";
       event.group = "ftrace";
-      event.ftrace_event_id = 20;
+      event.ftrace_event_id = kFakePrintEventId;
       events.push_back(event);
     }
 
     return std::unique_ptr<ProtoTranslationTable>(new ProtoTranslationTable(
         &table_procfs_, events, std::move(common_fields),
-        ProtoTranslationTable::DefaultPageHeaderSpecForTesting()));
+        ProtoTranslationTable::DefaultPageHeaderSpecForTesting(),
+        compact_format));
   }
 
   NiceMock<MockFtraceProcfs> table_procfs_;
@@ -204,10 +215,11 @@
   EXPECT_CALL(*mock_table, GetEvent(GroupAndName("power", "cpu_frequency")))
       .Times(AnyNumber());
 
+  static constexpr int kExpectedEventId = 77;
   Event event_to_return;
   event_to_return.name = "cpu_frequency";
   event_to_return.group = "power";
-  event_to_return.ftrace_event_id = 1;
+  event_to_return.ftrace_event_id = kExpectedEventId;
   ON_CALL(*mock_table, GetOrCreateEvent(GroupAndName("power", "cpu_frequency")))
       .WillByDefault(Return(&event_to_return));
   EXPECT_CALL(*mock_table,
@@ -215,9 +227,15 @@
 
   FtraceConfigId id = model.SetupConfig(config);
   ASSERT_TRUE(model.ActivateConfig(id));
-  const FtraceConfig* actual_config = model.GetConfigForTesting(id);
-  EXPECT_TRUE(actual_config);
-  EXPECT_THAT(actual_config->ftrace_events(), Contains("power/cpu_frequency"));
+
+  const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
+  ASSERT_TRUE(ds_config);
+  ASSERT_THAT(ds_config->event_filter.GetEnabledEvents(),
+              ElementsAreArray({kExpectedEventId}));
+
+  const EventFilter* central_filter = model.GetCentralEventFilterForTesting();
+  ASSERT_THAT(central_filter->GetEnabledEvents(),
+              ElementsAreArray({kExpectedEventId}));
 }
 
 TEST_F(FtraceConfigMuxerTest, AddSameNameEvents) {
@@ -228,28 +246,34 @@
 
   FtraceConfigMuxer model(&ftrace, mock_table.get());
 
+  static constexpr int kEventId1 = 1;
   Event event1;
   event1.name = "foo";
   event1.group = "group_one";
-  event1.ftrace_event_id = 1;
+  event1.ftrace_event_id = kEventId1;
   ON_CALL(*mock_table, GetOrCreateEvent(GroupAndName("group_one", "foo")))
       .WillByDefault(Return(&event1));
   EXPECT_CALL(*mock_table, GetOrCreateEvent(GroupAndName("group_one", "foo")));
 
+  static constexpr int kEventId2 = 2;
   Event event2;
   event2.name = "foo";
   event2.group = "group_two";
-  event2.ftrace_event_id = 2;
+  event2.ftrace_event_id = kEventId2;
   ON_CALL(*mock_table, GetOrCreateEvent(GroupAndName("group_two", "foo")))
       .WillByDefault(Return(&event2));
   EXPECT_CALL(*mock_table, GetOrCreateEvent(GroupAndName("group_two", "foo")));
 
   FtraceConfigId id = model.SetupConfig(config);
   ASSERT_TRUE(model.ActivateConfig(id));
-  const FtraceConfig* actual_config = model.GetConfigForTesting(id);
-  EXPECT_TRUE(actual_config);
-  EXPECT_THAT(actual_config->ftrace_events(), Contains("group_one/foo"));
-  EXPECT_THAT(actual_config->ftrace_events(), Contains("group_two/foo"));
+
+  const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
+  ASSERT_THAT(ds_config->event_filter.GetEnabledEvents(),
+              ElementsAreArray({kEventId1, kEventId2}));
+
+  const EventFilter* central_filter = model.GetCentralEventFilterForTesting();
+  ASSERT_THAT(central_filter->GetEnabledEvents(),
+              ElementsAreArray({kEventId1, kEventId2}));
 }
 
 TEST_F(FtraceConfigMuxerTest, AddAllEvents) {
@@ -281,9 +305,9 @@
   EXPECT_CALL(ftrace, GetEventNamesForGroup("events/sched")).Times(1);
 
   // Non-generic event.
-  std::map<std::string, const Event*> events;
+  static constexpr int kSchedSwitchEventId = 1;
   Event sched_switch = {"sched_switch", "sched", {}, 0, 0, 0};
-  sched_switch.ftrace_event_id = 1;
+  sched_switch.ftrace_event_id = kSchedSwitchEventId;
   ON_CALL(*mock_table, GetOrCreateEvent(GroupAndName("sched", "sched_switch")))
       .WillByDefault(Return(&sched_switch));
   EXPECT_CALL(*mock_table,
@@ -291,10 +315,11 @@
       .Times(AnyNumber());
 
   // Generic event.
+  static constexpr int kGenericEventId = 2;
   Event event_to_return;
   event_to_return.name = "sched_new_event";
   event_to_return.group = "sched";
-  event_to_return.ftrace_event_id = 2;
+  event_to_return.ftrace_event_id = kGenericEventId;
   ON_CALL(*mock_table,
           GetOrCreateEvent(GroupAndName("sched", "sched_new_event")))
       .WillByDefault(Return(&event_to_return));
@@ -305,10 +330,14 @@
   ASSERT_TRUE(id);
   ASSERT_TRUE(model.ActivateConfig(id));
 
-  const FtraceConfig* actual_config = model.GetConfigForTesting(id);
-  EXPECT_THAT(actual_config->ftrace_events(), Contains("sched/sched_switch"));
-  EXPECT_THAT(actual_config->ftrace_events(),
-              Contains("sched/sched_new_event"));
+  const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
+  ASSERT_TRUE(ds_config);
+  ASSERT_THAT(ds_config->event_filter.GetEnabledEvents(),
+              ElementsAreArray({kSchedSwitchEventId, kGenericEventId}));
+
+  const EventFilter* central_filter = model.GetCentralEventFilterForTesting();
+  ASSERT_THAT(central_filter->GetEnabledEvents(),
+              ElementsAreArray({kSchedSwitchEventId, kGenericEventId}));
 }
 
 TEST_F(FtraceConfigMuxerTest, TwoWildcardGroups) {
@@ -330,28 +359,35 @@
   EXPECT_CALL(ftrace, GetEventNamesForGroup("events/group_two"))
       .Times(AnyNumber());
 
+  static constexpr int kEventId1 = 1;
   Event event1;
   event1.name = "foo";
   event1.group = "group_one";
-  event1.ftrace_event_id = 1;
+  event1.ftrace_event_id = kEventId1;
   ON_CALL(*mock_table, GetOrCreateEvent(GroupAndName("group_one", "foo")))
       .WillByDefault(Return(&event1));
   EXPECT_CALL(*mock_table, GetOrCreateEvent(GroupAndName("group_one", "foo")));
 
+  static constexpr int kEventId2 = 2;
   Event event2;
   event2.name = "foo";
   event2.group = "group_two";
-  event2.ftrace_event_id = 2;
+  event2.ftrace_event_id = kEventId2;
   ON_CALL(*mock_table, GetOrCreateEvent(GroupAndName("group_two", "foo")))
       .WillByDefault(Return(&event2));
   EXPECT_CALL(*mock_table, GetOrCreateEvent(GroupAndName("group_two", "foo")));
 
   FtraceConfigId id = model.SetupConfig(config);
   ASSERT_TRUE(model.ActivateConfig(id));
-  const FtraceConfig* actual_config = model.GetConfigForTesting(id);
-  EXPECT_TRUE(actual_config);
-  EXPECT_THAT(actual_config->ftrace_events(), Contains("group_one/foo"));
-  EXPECT_THAT(actual_config->ftrace_events(), Contains("group_two/foo"));
+
+  const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
+  ASSERT_TRUE(ds_config);
+  ASSERT_THAT(ds_config->event_filter.GetEnabledEvents(),
+              ElementsAreArray({kEventId1, kEventId2}));
+
+  const EventFilter* central_filter = model.GetCentralEventFilterForTesting();
+  ASSERT_THAT(central_filter->GetEnabledEvents(),
+              ElementsAreArray({kEventId1, kEventId2}));
 }
 
 TEST_F(FtraceConfigMuxerTest, TurnFtraceOnOff) {
@@ -374,14 +410,24 @@
   EXPECT_CALL(ftrace, WriteToFile("/root/tracing_on", "1"));
   EXPECT_CALL(ftrace,
               WriteToFile("/root/events/sched/sched_switch/enable", "1"));
+
   FtraceConfigId id = model.SetupConfig(config);
   ASSERT_TRUE(id);
   ASSERT_TRUE(model.ActivateConfig(id));
 
-  const FtraceConfig* actual_config = model.GetConfigForTesting(id);
-  EXPECT_TRUE(actual_config);
-  EXPECT_THAT(actual_config->ftrace_events(), Contains("sched/sched_switch"));
-  EXPECT_THAT(actual_config->ftrace_events(), Not(Contains("foo")));
+  const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
+  ASSERT_TRUE(ds_config);
+  ASSERT_THAT(
+      ds_config->event_filter.GetEnabledEvents(),
+      ElementsAreArray({FtraceConfigMuxerTest::kFakeSchedSwitchEventId}));
+
+  const EventFilter* central_filter = model.GetCentralEventFilterForTesting();
+  ASSERT_THAT(
+      central_filter->GetEnabledEvents(),
+      ElementsAreArray({FtraceConfigMuxerTest::kFakeSchedSwitchEventId}));
+
+  ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(&ftrace));
+  EXPECT_CALL(ftrace, NumberOfCpus()).Times(AnyNumber());
 
   EXPECT_CALL(ftrace, WriteToFile("/root/tracing_on", "0"));
   EXPECT_CALL(ftrace, WriteToFile("/root/buffer_size_kb", "4"));
@@ -390,6 +436,7 @@
               WriteToFile("/root/events/sched/sched_switch/enable", "0"));
   EXPECT_CALL(ftrace, ClearFile("/root/trace"));
   EXPECT_CALL(ftrace, ClearFile(MatchesRegex("/root/per_cpu/cpu[0-9]/trace")));
+
   ASSERT_TRUE(model.RemoveConfig(id));
 }
 
@@ -426,10 +473,19 @@
   FtraceConfigId id = model.SetupConfig(config);
   ASSERT_TRUE(id);
 
-  const FtraceConfig* actual_config = model.GetConfigForTesting(id);
-  EXPECT_TRUE(actual_config);
-  EXPECT_THAT(actual_config->ftrace_events(), Contains("sched/sched_switch"));
-  EXPECT_THAT(actual_config->ftrace_events(), Contains("ftrace/print"));
+  // "ftrace" group events are always enabled, and therefore the "print" event
+  // will show up in the per data source event filter (as we want to record it),
+  // but not the central filter (as we're not enabling/disabling it).
+  const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
+  ASSERT_TRUE(ds_config);
+  EXPECT_THAT(ds_config->event_filter.GetEnabledEvents(),
+              Contains(FtraceConfigMuxerTest::kFakeSchedSwitchEventId));
+  EXPECT_THAT(ds_config->event_filter.GetEnabledEvents(),
+              Contains(FtraceConfigMuxerTest::kFakePrintEventId));
+
+  const EventFilter* central_filter = model.GetCentralEventFilterForTesting();
+  EXPECT_THAT(central_filter->GetEnabledEvents(),
+              Contains(FtraceConfigMuxerTest::kFakeSchedSwitchEventId));
 
   EXPECT_CALL(atrace, RunAtrace(ElementsAreArray(
                           {"atrace", "--async_stop", "--only_userspace"})))
@@ -459,9 +515,10 @@
   FtraceConfigId id = model.SetupConfig(config);
   ASSERT_TRUE(id);
 
-  const FtraceConfig* actual_config = model.GetConfigForTesting(id);
-  EXPECT_TRUE(actual_config);
-  EXPECT_THAT(actual_config->ftrace_events(), Contains("ftrace/print"));
+  const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
+  ASSERT_TRUE(ds_config);
+  ASSERT_THAT(ds_config->event_filter.GetEnabledEvents(),
+              Contains(FtraceConfigMuxerTest::kFakePrintEventId));
 
   EXPECT_CALL(atrace, RunAtrace(ElementsAreArray(
                           {"atrace", "--async_stop", "--only_userspace"})))
@@ -573,10 +630,18 @@
   ASSERT_TRUE(id);
   ASSERT_TRUE(model.ActivateConfig(id));
 
-  const FtraceConfig* actual_config = model.GetConfigForTesting(id);
-  EXPECT_TRUE(actual_config);
-  EXPECT_THAT(actual_config->ftrace_events(), Contains("sched/sched_switch"));
-  EXPECT_THAT(actual_config->ftrace_events(), Contains("cgroup/cgroup_mkdir"));
+  const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
+  ASSERT_TRUE(ds_config);
+  EXPECT_THAT(ds_config->event_filter.GetEnabledEvents(),
+              Contains(FtraceConfigMuxerTest::kFakeSchedSwitchEventId));
+  EXPECT_THAT(ds_config->event_filter.GetEnabledEvents(),
+              Contains(FtraceConfigMuxerTest::kCgroupMkdirEventId));
+
+  const EventFilter* central_filter = model.GetCentralEventFilterForTesting();
+  EXPECT_THAT(central_filter->GetEnabledEvents(),
+              Contains(FtraceConfigMuxerTest::kFakeSchedSwitchEventId));
+  EXPECT_THAT(central_filter->GetEnabledEvents(),
+              Contains(FtraceConfigMuxerTest::kCgroupMkdirEventId));
 
   EXPECT_CALL(ftrace, WriteToFile("/root/tracing_on", "0"));
   EXPECT_CALL(ftrace, WriteToFile("/root/buffer_size_kb", "4"));
@@ -593,5 +658,63 @@
   ASSERT_TRUE(model.RemoveConfig(id));
 }
 
+TEST_F(FtraceConfigMuxerTest, CompactSchedConfig) {
+  // Set scheduling event format as validated. The pre-parsed format itself
+  // doesn't need to be sensible, as the tests won't use it.
+  auto valid_compact_format = CompactSchedEventFormat{
+      /*format_valid=*/true, CompactSchedSwitchFormat{}};
+
+  NiceMock<MockFtraceProcfs> ftrace;
+  table_ = CreateFakeTable(valid_compact_format);
+  FtraceConfigMuxer model(&ftrace, table_.get());
+
+  // First data source - request compact encoding.
+  FtraceConfig config_enabled = CreateFtraceConfig({"sched/sched_switch"});
+  config_enabled.mutable_compact_sched()->set_enabled(true);
+
+  // Second data source - no compact encoding (default).
+  FtraceConfig config_disabled = CreateFtraceConfig({"sched/sched_switch"});
+
+  {
+    FtraceConfigId id = model.SetupConfig(config_enabled);
+    ASSERT_TRUE(id);
+    const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
+    ASSERT_TRUE(ds_config);
+    EXPECT_THAT(ds_config->event_filter.GetEnabledEvents(),
+                Contains(FtraceConfigMuxerTest::kFakeSchedSwitchEventId));
+    EXPECT_TRUE(ds_config->compact_sched.enabled);
+  }
+  {
+    FtraceConfigId id = model.SetupConfig(config_disabled);
+    ASSERT_TRUE(id);
+    const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
+    ASSERT_TRUE(ds_config);
+    EXPECT_THAT(ds_config->event_filter.GetEnabledEvents(),
+                Contains(FtraceConfigMuxerTest::kFakeSchedSwitchEventId));
+    EXPECT_FALSE(ds_config->compact_sched.enabled);
+  }
+}
+
+TEST_F(FtraceConfigMuxerTest, CompactSchedConfigWithInvalidFormat) {
+  NiceMock<MockFtraceProcfs> ftrace;
+  FtraceConfigMuxer model(&ftrace, table_.get());
+
+  // Request compact encoding.
+  FtraceConfig config = CreateFtraceConfig({"sched/sched_switch"});
+  config.mutable_compact_sched()->set_enabled(true);
+
+  FtraceConfigId id = model.SetupConfig(config);
+  ASSERT_TRUE(id);
+
+  // The translation table says that the scheduling events' format didn't match
+  // compile-time assumptions, so we won't enable compact events even if
+  // requested.
+  const FtraceDataSourceConfig* ds_config = model.GetDataSourceConfig(id);
+  ASSERT_TRUE(ds_config);
+  EXPECT_THAT(ds_config->event_filter.GetEnabledEvents(),
+              Contains(FtraceConfigMuxerTest::kFakeSchedSwitchEventId));
+  EXPECT_FALSE(ds_config->compact_sched.enabled);
+}
+
 }  // namespace
 }  // namespace perfetto
diff --git a/src/traced/probes/ftrace/ftrace_controller.cc b/src/traced/probes/ftrace/ftrace_controller.cc
index 5485fef..0732527 100644
--- a/src/traced/probes/ftrace/ftrace_controller.cc
+++ b/src/traced/probes/ftrace/ftrace_controller.cc
@@ -34,6 +34,7 @@
 #include "perfetto/ext/base/file_utils.h"
 #include "perfetto/ext/base/metatrace.h"
 #include "perfetto/ext/tracing/core/trace_writer.h"
+#include "src/traced/probes/ftrace/compact_sched.h"
 #include "src/traced/probes/ftrace/cpu_reader.h"
 #include "src/traced/probes/ftrace/cpu_stats_parser.h"
 #include "src/traced/probes/ftrace/event_info.h"
@@ -51,19 +52,33 @@
 constexpr int kMinDrainPeriodMs = 1;
 constexpr int kMaxDrainPeriodMs = 1000 * 60;
 
-// When reading and parsing data for a particular cpu, we do it in batches of
-// this many pages. In other words, we'll read up to
-// |kParsingBufferSizePages| into memory, parse them, and then repeat if we
-// still haven't caught up to the writer. A working set of 32 pages is 128k of
-// data, which should fit in a typical L1D cache. Furthermore, the batching
-// limits the memory usage of traced_probes.
-constexpr size_t kParsingBufferSizePages = 32;
-
 // Read at most this many pages of data per cpu per read task. If we hit this
 // limit on at least one cpu, we stop and repost the read task, letting other
 // tasks get some cpu time before continuing reading.
 constexpr size_t kMaxPagesPerCpuPerReadTick = 256;  // 1 MB per cpu
 
+// When reading and parsing data for a particular cpu, we do it in batches of
+// this many pages. In other words, we'll read up to
+// |kParsingBufferSizePages| into memory, parse them, and then repeat if we
+// still haven't caught up to the writer. A working set of 32 pages is 128k of
+// data, which should fit in a typical L2D cache. Furthermore, the batching
+// limits the memory usage of traced_probes.
+//
+// Note that the compact scheduler event encoding buffers operate on the same
+// buffer size, and their maximum capacity is set at compile-time as it lives on
+// the stack. So the maximum possible number of events encoded in this many
+// tracing pages must not exceed compact_sched's capacity. See the static_assert
+// below.
+// TODO(rsavitski): consider making buffering & parsing page counts independent,
+// should be a single counter in the cpu_reader, similar to lost_events case.
+constexpr size_t kParsingBufferSizePages = 32;
+
+static_assert(kParsingBufferSizePages *
+                      (base::kPageSize /
+                       CompactSchedBundleState::kMinSupportedSchedSwitchSize) <=
+                  CompactSchedBundleState::kMaxElements,
+              "insufficient compact_sched buffer capacity");
+
 uint32_t ClampDrainPeriodMs(uint32_t drain_period_ms) {
   if (drain_period_ms == 0) {
     return kDefaultDrainPeriodMs;
@@ -181,7 +196,7 @@
   size_t period_page_quota = ftrace_config_muxer_->GetPerCpuBufferSizePages();
   for (size_t cpu = 0; cpu < ftrace_procfs_->NumberOfCpus(); cpu++) {
     auto reader = std::unique_ptr<CpuReader>(
-        new CpuReader(table_.get(), cpu, ftrace_procfs_->OpenPipeForCpu(cpu)));
+        new CpuReader(cpu, table_.get(), ftrace_procfs_->OpenPipeForCpu(cpu)));
     per_cpu_.emplace_back(std::move(reader), period_page_quota);
   }
 
@@ -346,10 +361,11 @@
   if (!config_id)
     return false;
 
-  const EventFilter* filter = ftrace_config_muxer_->GetEventFilter(config_id);
+  const FtraceDataSourceConfig* ds_config =
+      ftrace_config_muxer_->GetDataSourceConfig(config_id);
   auto it_and_inserted = data_sources_.insert(data_source);
   PERFETTO_DCHECK(it_and_inserted.second);
-  data_source->Initialize(config_id, filter);
+  data_source->Initialize(config_id, ds_config);
   return true;
 }
 
diff --git a/src/traced/probes/ftrace/ftrace_controller_unittest.cc b/src/traced/probes/ftrace/ftrace_controller_unittest.cc
index feb49f8..6622ee2 100644
--- a/src/traced/probes/ftrace/ftrace_controller_unittest.cc
+++ b/src/traced/probes/ftrace/ftrace_controller_unittest.cc
@@ -20,6 +20,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
+#include "src/traced/probes/ftrace/compact_sched.h"
 #include "src/traced/probes/ftrace/cpu_reader.h"
 #include "src/traced/probes/ftrace/ftrace_config_muxer.h"
 #include "src/traced/probes/ftrace/ftrace_config_utils.h"
@@ -85,7 +86,8 @@
 
   return std::unique_ptr<Table>(
       new Table(ftrace, events, std::move(common_fields),
-                ProtoTranslationTable::DefaultPageHeaderSpecForTesting()));
+                ProtoTranslationTable::DefaultPageHeaderSpecForTesting(),
+                InvalidCompactSchedEventFormatForTesting()));
 }
 
 std::unique_ptr<FtraceConfigMuxer> FakeModel(FtraceProcfs* ftrace,
@@ -473,12 +475,10 @@
   FtraceMetadata metadata;
   metadata.inode_and_device.push_back(std::make_pair(1, 1));
   metadata.pids.push_back(2);
-  metadata.lost_events = true;
   metadata.last_seen_device_id = 100;
   metadata.Clear();
   EXPECT_THAT(metadata.inode_and_device, IsEmpty());
   EXPECT_THAT(metadata.pids, IsEmpty());
-  EXPECT_FALSE(metadata.lost_events);
   EXPECT_EQ(BlockDeviceID(0), metadata.last_seen_device_id);
 }
 
diff --git a/src/traced/probes/ftrace/ftrace_data_source.cc b/src/traced/probes/ftrace/ftrace_data_source.cc
index 6078c91..f576f16 100644
--- a/src/traced/probes/ftrace/ftrace_data_source.cc
+++ b/src/traced/probes/ftrace/ftrace_data_source.cc
@@ -43,11 +43,12 @@
     controller_weak_->RemoveDataSource(this);
 };
 
-void FtraceDataSource::Initialize(FtraceConfigId config_id,
-                                  const EventFilter* event_filter) {
+void FtraceDataSource::Initialize(
+    FtraceConfigId config_id,
+    const FtraceDataSourceConfig* parsing_config) {
   PERFETTO_CHECK(config_id);
   config_id_ = config_id;
-  event_filter_ = event_filter;
+  parsing_config_ = parsing_config;
 }
 
 void FtraceDataSource::Start() {
diff --git a/src/traced/probes/ftrace/ftrace_data_source.h b/src/traced/probes/ftrace/ftrace_data_source.h
index 04e50f5..1730616 100644
--- a/src/traced/probes/ftrace/ftrace_data_source.h
+++ b/src/traced/probes/ftrace/ftrace_data_source.h
@@ -36,10 +36,10 @@
 
 namespace perfetto {
 
-class EventFilter;
 class FtraceController;
 class ProcessStatsDataSource;
 class InodeFileDataSource;
+struct FtraceDataSourceConfig;
 
 namespace protos {
 namespace pbzero {
@@ -63,7 +63,7 @@
 
   // Called by FtraceController soon after ProbesProducer creates the data
   // source, to inject ftrace dependencies.
-  void Initialize(FtraceConfigId, const EventFilter* event_filter);
+  void Initialize(FtraceConfigId, const FtraceDataSourceConfig* parsing_config);
 
   // ProbesDataSource implementation.
   void Start() override;
@@ -75,7 +75,10 @@
 
   FtraceConfigId config_id() const { return config_id_; }
   const FtraceConfig& config() const { return config_; }
-  const EventFilter* event_filter() { return event_filter_; }
+  const FtraceDataSourceConfig* parsing_config() const {
+    return parsing_config_;
+  }
+
   FtraceMetadata* mutable_metadata() { return &metadata_; }
   TraceWriter* trace_writer() { return writer_.get(); }
 
@@ -91,11 +94,14 @@
   FtraceStats stats_before_ = {};
   std::map<FlushRequestID, std::function<void()>> pending_flushes_;
 
-  // Initialized by the Initialize() call.
+  // -- Fields initialized by the Initialize() call:
   FtraceConfigId config_id_ = 0;
   std::unique_ptr<TraceWriter> writer_;
   base::WeakPtr<FtraceController> controller_weak_;
-  const EventFilter* event_filter_;
+  // Muxer-held state for parsing ftrace according to this data source's
+  // configuration. Not the raw FtraceConfig proto (held by |config_|).
+  const FtraceDataSourceConfig* parsing_config_;
+  // -- End of fields set by Initialize().
 };
 
 }  // namespace perfetto
diff --git a/src/traced/probes/ftrace/ftrace_metadata.cc b/src/traced/probes/ftrace/ftrace_metadata.cc
index 93af4ae..c719a67 100644
--- a/src/traced/probes/ftrace/ftrace_metadata.cc
+++ b/src/traced/probes/ftrace/ftrace_metadata.cc
@@ -81,7 +81,6 @@
   inode_and_device.clear();
   pids.clear();
   rename_pids.clear();
-  lost_events = false;
   FinishEvent();
 }
 
diff --git a/src/traced/probes/ftrace/ftrace_metadata.h b/src/traced/probes/ftrace/ftrace_metadata.h
index b2fe916..ac37def 100644
--- a/src/traced/probes/ftrace/ftrace_metadata.h
+++ b/src/traced/probes/ftrace/ftrace_metadata.h
@@ -31,10 +31,11 @@
 using BlockDeviceID = decltype(stat::st_dev);
 using Inode = decltype(stat::st_ino);
 
+// Container for tracking miscellaneous information while parsing ftrace events,
+// scoped to an individual data source.
 struct FtraceMetadata {
   FtraceMetadata();
 
-  bool lost_events = false;
   BlockDeviceID last_seen_device_id = 0;
 #if PERFETTO_DCHECK_IS_ON()
   bool seen_device_id = false;
diff --git a/src/traced/probes/ftrace/proto_translation_table.cc b/src/traced/probes/ftrace/proto_translation_table.cc
index 4c56935..405aeaa 100644
--- a/src/traced/probes/ftrace/proto_translation_table.cc
+++ b/src/traced/probes/ftrace/proto_translation_table.cc
@@ -447,8 +447,13 @@
                               }),
                events.end());
 
-  auto table = std::unique_ptr<ProtoTranslationTable>(new ProtoTranslationTable(
-      ftrace_procfs, events, std::move(common_fields), header_spec));
+  // Pre-parse certain scheduler events, and see if the compile-time assumptions
+  // about their format hold for this kernel.
+  CompactSchedEventFormat compact_sched = ValidateFormatForCompactSched(events);
+
+  auto table = std::unique_ptr<ProtoTranslationTable>(
+      new ProtoTranslationTable(ftrace_procfs, events, std::move(common_fields),
+                                header_spec, compact_sched));
   return table;
 }
 
@@ -456,12 +461,14 @@
     const FtraceProcfs* ftrace_procfs,
     const std::vector<Event>& events,
     std::vector<Field> common_fields,
-    FtracePageHeaderSpec ftrace_page_header_spec)
+    FtracePageHeaderSpec ftrace_page_header_spec,
+    CompactSchedEventFormat compact_sched_format)
     : ftrace_procfs_(ftrace_procfs),
       events_(BuildEventsVector(events)),
       largest_id_(events_.size() - 1),
       common_fields_(std::move(common_fields)),
-      ftrace_page_header_spec_(ftrace_page_header_spec) {
+      ftrace_page_header_spec_(ftrace_page_header_spec),
+      compact_sched_format_(compact_sched_format) {
   for (const Event& event : events) {
     group_and_name_to_event_[GroupAndName(event.group, event.name)] =
         &events_.at(event.ftrace_event_id);
diff --git a/src/traced/probes/ftrace/proto_translation_table.h b/src/traced/probes/ftrace/proto_translation_table.h
index ea5ff90..f9c5be6 100644
--- a/src/traced/probes/ftrace/proto_translation_table.h
+++ b/src/traced/probes/ftrace/proto_translation_table.h
@@ -26,6 +26,7 @@
 #include <vector>
 
 #include "perfetto/ext/base/scoped_file.h"
+#include "src/traced/probes/ftrace/compact_sched.h"
 #include "src/traced/probes/ftrace/event_info.h"
 #include "src/traced/probes/ftrace/format_parser.h"
 
@@ -91,7 +92,8 @@
   ProtoTranslationTable(const FtraceProcfs* ftrace_procfs,
                         const std::vector<Event>& events,
                         std::vector<Field> common_fields,
-                        FtracePageHeaderSpec ftrace_page_header_spec);
+                        FtracePageHeaderSpec ftrace_page_header_spec,
+                        CompactSchedEventFormat compact_sched_format);
 
   size_t largest_id() const { return largest_id_; }
 
@@ -151,6 +153,10 @@
     return name_to_events_.at(name)[0];
   }
 
+  const CompactSchedEventFormat& compact_sched_format() const {
+    return compact_sched_format_;
+  }
+
  private:
   ProtoTranslationTable(const ProtoTranslationTable&) = delete;
   ProtoTranslationTable& operator=(const ProtoTranslationTable&) = delete;
@@ -170,6 +176,7 @@
   std::vector<Field> common_fields_;
   FtracePageHeaderSpec ftrace_page_header_spec_{};
   std::set<std::string> interned_strings_;
+  CompactSchedEventFormat compact_sched_format_;
 };
 
 // Class for efficient 'is event with id x enabled?' checks.
diff --git a/src/traced/probes/ftrace/proto_translation_table_unittest.cc b/src/traced/probes/ftrace/proto_translation_table_unittest.cc
index 5448ba1..f3841d9 100644
--- a/src/traced/probes/ftrace/proto_translation_table_unittest.cc
+++ b/src/traced/probes/ftrace/proto_translation_table_unittest.cc
@@ -20,6 +20,7 @@
 #include "protos/perfetto/trace/ftrace/generic.pbzero.h"
 #include "src/base/test/gtest_test_suite.h"
 #include "src/base/test/utils.h"
+#include "src/traced/probes/ftrace/compact_sched.h"
 #include "src/traced/probes/ftrace/event_info.h"
 #include "src/traced/probes/ftrace/ftrace_procfs.h"
 #include "test/gtest_and_gmock.h"
@@ -258,6 +259,53 @@
 
 INSTANTIATE_TEST_SUITE_P(BySize, TranslationTableCreationTest, Values(4, 8));
 
+TEST(TranslationTableTest, CompactSchedFormatParsingSeedData) {
+  std::string path =
+      "src/traced/probes/ftrace/test/data/android_seed_N2F62_3.10.49/";
+  FtraceProcfs ftrace_procfs(path);
+  auto table = ProtoTranslationTable::Create(
+      &ftrace_procfs, GetStaticEventInfo(), GetStaticCommonFieldsInfo());
+  PERFETTO_CHECK(table);
+  const CompactSchedEventFormat& format = table->compact_sched_format();
+
+  // Format matches compile-time assumptions.
+  ASSERT_TRUE(format.format_valid);
+
+  // Check exact format (note: 32 bit long prev_state).
+  EXPECT_EQ(68u, format.sched_switch.event_id);
+  EXPECT_EQ(60u, format.sched_switch.size);
+  EXPECT_EQ(52u, format.sched_switch.next_pid_offset);
+  EXPECT_EQ(FtraceFieldType::kFtracePid32, format.sched_switch.next_pid_type);
+  EXPECT_EQ(56u, format.sched_switch.next_prio_offset);
+  EXPECT_EQ(FtraceFieldType::kFtraceInt32, format.sched_switch.next_prio_type);
+  EXPECT_EQ(32u, format.sched_switch.prev_state_offset);
+  EXPECT_EQ(FtraceFieldType::kFtraceInt32, format.sched_switch.prev_state_type);
+  EXPECT_EQ(36u, format.sched_switch.next_comm_offset);
+}
+
+TEST(TranslationTableTest, CompactSchedFormatParsingSyntheticData) {
+  std::string path = "src/traced/probes/ftrace/test/data/synthetic/";
+  FtraceProcfs ftrace_procfs(path);
+  auto table = ProtoTranslationTable::Create(
+      &ftrace_procfs, GetStaticEventInfo(), GetStaticCommonFieldsInfo());
+  PERFETTO_CHECK(table);
+  const CompactSchedEventFormat& format = table->compact_sched_format();
+
+  // Format matches compile-time assumptions.
+  ASSERT_TRUE(format.format_valid);
+
+  // Check exact format (note: 64 bit long prev_state).
+  EXPECT_EQ(47u, format.sched_switch.event_id);
+  EXPECT_EQ(64u, format.sched_switch.size);
+  EXPECT_EQ(56u, format.sched_switch.next_pid_offset);
+  EXPECT_EQ(FtraceFieldType::kFtracePid32, format.sched_switch.next_pid_type);
+  EXPECT_EQ(60u, format.sched_switch.next_prio_offset);
+  EXPECT_EQ(FtraceFieldType::kFtraceInt32, format.sched_switch.next_prio_type);
+  EXPECT_EQ(32u, format.sched_switch.prev_state_offset);
+  EXPECT_EQ(FtraceFieldType::kFtraceInt64, format.sched_switch.prev_state_type);
+  EXPECT_EQ(40u, format.sched_switch.next_comm_offset);
+}
+
 TEST(TranslationTableTest, InferFtraceType) {
   FtraceFieldType type;
 
@@ -341,7 +389,9 @@
 
   ProtoTranslationTable table(
       &ftrace, events, std::move(common_fields),
-      ProtoTranslationTable::DefaultPageHeaderSpecForTesting());
+      ProtoTranslationTable::DefaultPageHeaderSpecForTesting(),
+      InvalidCompactSchedEventFormatForTesting());
+
   EXPECT_EQ(table.largest_id(), 100ul);
   EXPECT_EQ(table.EventToFtraceId(GroupAndName("group_one", "foo")), 1ul);
   EXPECT_EQ(table.EventToFtraceId(GroupAndName("group_two", "baz")), 100ul);
diff --git a/src/traced/probes/ftrace/test/cpu_reader_support.h b/src/traced/probes/ftrace/test/cpu_reader_support.h
index d73ebcc..ab91932 100644
--- a/src/traced/probes/ftrace/test/cpu_reader_support.h
+++ b/src/traced/probes/ftrace/test/cpu_reader_support.h
@@ -32,7 +32,7 @@
   const char* data;
 };
 
-// Create a ProtoTranslationTable uing the fomat files in
+// Create a ProtoTranslationTable using the fomat files in
 // directory |name|. Caches the table for subsequent lookups.
 ProtoTranslationTable* GetTable(const std::string& name);
 
diff --git a/src/tracing/core/tracing_service_impl.cc b/src/tracing/core/tracing_service_impl.cc
index 4596a01..c87f6a8 100644
--- a/src/tracing/core/tracing_service_impl.cc
+++ b/src/tracing/core/tracing_service_impl.cc
@@ -2149,7 +2149,7 @@
 }
 
 void TracingServiceImpl::SnapshotSyncMarker(std::vector<TracePacket>* packets) {
-  // The sync markes is used to tokenize large traces efficiently.
+  // The sync marks are used to tokenize large traces efficiently.
   // See description in trace_packet.proto.
   if (sync_marker_packet_size_ == 0) {
     // Serialize the marker and the uid separately to guarantee that the marker
diff --git a/test/cts/README.md b/test/cts/README.md
index c76856d..02b5bdb 100644
--- a/test/cts/README.md
+++ b/test/cts/README.md
@@ -24,8 +24,8 @@
 
 The mock producer is an Android app with a thin Java wrapping around the C++
 library interfaced using JNI. The purpose of this target is to ensure that the
-TraceProto received from the consumer is valid and and then push some fake data.
-This ensures that any arbitary app can push data to the Perfetto socket which
+TraceProto received from the consumer is valid and then push some fake data.
+This ensures that any arbitrary app can push data to the Perfetto socket which
 can then be decoded by the GTest consumer.
 
 ## HeapprofdCtsTest
diff --git a/test/cts/heapprofd_test_cts.cc b/test/cts/heapprofd_test_cts.cc
index 15eafcb..c2d37dd 100644
--- a/test/cts/heapprofd_test_cts.cc
+++ b/test/cts/heapprofd_test_cts.cc
@@ -231,28 +231,21 @@
   system(stop_cmd.c_str());
 }
 
-// TODO(b/118428762): look into unwinding issues on x86.
-#if defined(__i386__) || defined(__x86_64__)
-#define MAYBE_SKIP(x) DISABLED_##x
-#else
-#define MAYBE_SKIP(x) x
-#endif
-
-TEST(HeapprofdCtsTest, MAYBE_SKIP(DebuggableAppRuntime)) {
+TEST(HeapprofdCtsTest, DebuggableAppRuntime) {
   std::string app_name = "android.perfetto.cts.app.debuggable";
   const auto& packets = ProfileRuntime(app_name);
   AssertExpectedAllocationsPresent(packets);
   StopApp(app_name);
 }
 
-TEST(HeapprofdCtsTest, MAYBE_SKIP(DebuggableAppStartup)) {
+TEST(HeapprofdCtsTest, DebuggableAppStartup) {
   std::string app_name = "android.perfetto.cts.app.debuggable";
   const auto& packets = ProfileStartup(app_name);
   AssertExpectedAllocationsPresent(packets);
   StopApp(app_name);
 }
 
-TEST(HeapprofdCtsTest, MAYBE_SKIP(ReleaseAppRuntime)) {
+TEST(HeapprofdCtsTest, ReleaseAppRuntime) {
   std::string app_name = "android.perfetto.cts.app.release";
   const auto& packets = ProfileRuntime(app_name);
 
@@ -264,7 +257,7 @@
   StopApp(app_name);
 }
 
-TEST(HeapprofdCtsTest, MAYBE_SKIP(ReleaseAppStartup)) {
+TEST(HeapprofdCtsTest, ReleaseAppStartup) {
   std::string app_name = "android.perfetto.cts.app.release";
   const auto& packets = ProfileStartup(app_name);
 
diff --git a/test/end_to_end_integrationtest.cc b/test/end_to_end_integrationtest.cc
index 3c0d3f3..ea28c95 100644
--- a/test/end_to_end_integrationtest.cc
+++ b/test/end_to_end_integrationtest.cc
@@ -72,7 +72,7 @@
 // This class is a reference to a child process that has in essence been execv
 // to the requested binary. The process will start and then wait for Run()
 // before proceeding. We use this to fork new processes before starting any
-// additional threads in the parent proces (otherwise you would risk
+// additional threads in the parent process (otherwise you would risk
 // deadlocks), but pause the forked processes until remaining setup (including
 // any necessary threads) in the parent process is complete.
 class Exec {
diff --git a/test/trace_processor/gpu_render_stages.out b/test/trace_processor/gpu_render_stages.out
index 3fb1a4d..ab28793 100644
--- a/test/trace_processor/gpu_render_stages.out
+++ b/test/trace_processor/gpu_render_stages.out
@@ -1,19 +1,19 @@
-"ts","dur","ref","ref_type","name","depth","arg_set_id","flat_key","string_value"
-10,5,1,"gpu","stage 1",0,1,"keyOnlyTest","[NULL]"
-10,5,1,"gpu","stage 1",0,1,"stencilBPP","1"
-10,5,1,"gpu","stage 1",0,1,"height","1.000000"
-20,5,0,"gpu","stage 2",0,2,"keyOnlyTest","[NULL]"
-20,5,0,"gpu","stage 2",0,2,"height","4.000000"
-30,5,1,"gpu","stage 0",0,3,"keyOnlyTest","[NULL]"
-30,5,1,"gpu","stage 0",0,3,"stencilBPP","1"
-30,5,1,"gpu","stage 0",0,3,"height","9.000000"
-40,5,0,"gpu","stage 1",0,0,"[NULL]","[NULL]"
-50,5,1,"gpu","stage 2",0,4,"keyOnlyTest","[NULL]"
-50,5,1,"gpu","stage 2",0,4,"stencilBPP","1"
-50,5,1,"gpu","stage 2",0,4,"height","25.000000"
-60,5,0,"gpu","stage 0",0,5,"keyOnlyTest","[NULL]"
-60,5,0,"gpu","stage 0",0,5,"height","36.000000"
-70,5,1,"gpu","stage 1",0,6,"keyOnlyTest","[NULL]"
-70,5,1,"gpu","stage 1",0,6,"stencilBPP","1"
-70,5,1,"gpu","stage 1",0,6,"height","49.000000"
-80,5,0,"gpu","stage 2",0,0,"[NULL]","[NULL]"
+"ts","dur","ref","ref_type","name","depth","arg_set_id","flat_key","string_value","context_id","render_target","submission_id","hw_queue_id"
+10,5,1,"gpu","stage 1",0,1,"keyOnlyTest","[NULL]",42,0,0,1
+10,5,1,"gpu","stage 1",0,1,"stencilBPP","1",42,0,0,1
+10,5,1,"gpu","stage 1",0,1,"height","1.000000",42,0,0,1
+20,5,0,"gpu","stage 2",0,2,"keyOnlyTest","[NULL]",42,0,0,0
+20,5,0,"gpu","stage 2",0,2,"height","4.000000",42,0,0,0
+30,5,1,"gpu","stage 0",0,3,"keyOnlyTest","[NULL]",42,0,0,1
+30,5,1,"gpu","stage 0",0,3,"stencilBPP","1",42,0,0,1
+30,5,1,"gpu","stage 0",0,3,"height","9.000000",42,0,0,1
+40,5,0,"gpu","stage 1",0,0,"[NULL]","[NULL]",42,0,0,0
+50,5,1,"gpu","stage 2",0,4,"keyOnlyTest","[NULL]",42,0,0,1
+50,5,1,"gpu","stage 2",0,4,"stencilBPP","1",42,0,0,1
+50,5,1,"gpu","stage 2",0,4,"height","25.000000",42,0,0,1
+60,5,0,"gpu","stage 0",0,5,"keyOnlyTest","[NULL]",42,0,0,0
+60,5,0,"gpu","stage 0",0,5,"height","36.000000",42,0,0,0
+70,5,1,"gpu","stage 1",0,6,"keyOnlyTest","[NULL]",42,0,0,1
+70,5,1,"gpu","stage 1",0,6,"stencilBPP","1",42,0,0,1
+70,5,1,"gpu","stage 1",0,6,"height","49.000000",42,0,0,1
+80,5,0,"gpu","stage 2",0,0,"[NULL]","[NULL]",42,0,0,0
diff --git a/test/trace_processor/gpu_render_stages.sql b/test/trace_processor/gpu_render_stages.sql
index b558924..e08025b 100644
--- a/test/trace_processor/gpu_render_stages.sql
+++ b/test/trace_processor/gpu_render_stages.sql
@@ -1 +1,5 @@
-SELECT "ts","dur","ref","ref_type","name","depth", internal_slice.arg_set_id, "flat_key", "string_value" FROM internal_slice LEFT JOIN args ON internal_slice.arg_set_id = args.arg_set_id ORDER BY "ts";
+SELECT "ts","dur","ref","ref_type","name","depth", internal_slice.arg_set_id, "flat_key",
+       "string_value", "context_id", "render_target", "submission_id", "hw_queue_id" FROM internal_slice
+INNER JOIN gpu_slice USING(slice_id)
+LEFT JOIN args ON internal_slice.arg_set_id = args.arg_set_id
+ORDER BY "ts";
diff --git a/tools/gen_amalgamated b/tools/gen_amalgamated
index 307b73b..f869390 100755
--- a/tools/gen_amalgamated
+++ b/tools/gen_amalgamated
@@ -56,7 +56,7 @@
 # inlcude each other but rely on forward declarations. The alternative would
 # be adding each proto sub-target individually (e.g. //proto/trace/gpu:zero),
 # but doing that is unmaintainable.
-recurse_in_header_deps = '^//protos/.*'
+recurse_in_header_deps = '^//protos/.*zero$'
 
 # Compiler flags which aren't filtered out.
 cflag_whitelist = r'^-(W.*|fno-exceptions|fPIC|std.*|fvisibility.*)$'
diff --git a/tools/gen_android_bp b/tools/gen_android_bp
index b98ad9a..8bfe686 100755
--- a/tools/gen_android_bp
+++ b/tools/gen_android_bp
@@ -433,7 +433,7 @@
     # equivalents.
     target = desc[dep_name]
     for lib in target.get('libs', []):
-        # Generally library names sould be mangled as 'libXXX', unless they are
+        # Generally library names should be mangled as 'libXXX', unless they are
         # HAL libraries (e.g., android.hardware.health@2.0).
         android_lib = lib if '@' in lib else 'lib' + lib
         if lib in library_whitelist and not android_lib in module.shared_libs:
diff --git a/tools/gen_bazel b/tools/gen_bazel
index 282bf84..619679b 100755
--- a/tools/gen_bazel
+++ b/tools/gen_bazel
@@ -25,17 +25,280 @@
 
 from __future__ import print_function
 import argparse
-import functools
 import json
 import os
 import re
 import sys
-import textwrap
 
 import gn_utils
 
-# Copyright header for generated code.
-header = """# Copyright (C) 2019 The Android Open Source Project
+# Arguments for the GN output directory.
+# host_os="linux" is to generate the right build files from Mac OS.
+gn_args = ' '.join([
+    'host_os="linux"',
+    'is_debug=false',
+    'is_perfetto_build_generator=true',
+    'enable_perfetto_watchdog=true',
+    'monolithic_binaries=true',
+    'target_os="linux"',
+])
+
+# Default targets to translate to the blueprint file.
+
+# These targets will be exported with public visibility in the generated BUILD.
+public_targets = [
+    '//src/perfetto_cmd:perfetto',
+    '//src/traced/probes:traced_probes',
+    '//src/traced/service:traced',
+    '//src/trace_processor:trace_processor_shell',
+    '//src/trace_processor:trace_processor',
+    '//tools/trace_to_text:trace_to_text',
+    '//tools/trace_to_text:libpprofbuilder',
+]
+
+# These targets are required by internal build rules but don't need to be
+# exported publicly.
+default_targets = [
+    '//src/ipc:perfetto_ipc',
+    '//src/ipc/protoc_plugin:ipc_plugin',
+    '//src/protozero:libprotozero',
+    '//src/protozero/protoc_plugin:protozero_plugin',
+] + public_targets
+
+# Root proto targets (to force discovery of intermediate proto targets).
+proto_targets = [
+    '//protos/perfetto/metrics:lite',
+    '//protos/perfetto/trace:lite',
+    '//protos/perfetto/config:lite',
+]
+
+# The directory where the generated perfetto_build_flags.h will be copied into.
+buildflags_dir = 'include/perfetto/base/build_configs/bazel'
+
+# Internal equivalents for third-party libraries that the upstream project
+# depends on.
+external_deps = {
+    '//gn:default_deps': [],
+    '//gn:jsoncpp': ['PERFETTO_CONFIG.deps.jsoncpp'],
+    '//gn:linenoise': ['PERFETTO_CONFIG.deps.linenoise'],
+    '//gn:protobuf_full': ['PERFETTO_CONFIG.deps.protobuf_full'],
+    '//gn:protobuf_lite': ['PERFETTO_CONFIG.deps.protobuf_lite'],
+    '//gn:protoc_lib': ['PERFETTO_CONFIG.deps.protoc_lib'],
+    '//gn:protoc': ['PERFETTO_CONFIG.deps.protoc'],
+    '//gn:sqlite': [
+        'PERFETTO_CONFIG.deps.sqlite',
+        'PERFETTO_CONFIG.deps.sqlite_ext_percentile'
+    ],
+    '//gn:zlib': ['PERFETTO_CONFIG.deps.zlib'],
+    '//gn/standalone:gen_git_revision': [],
+    '//src/trace_processor/metrics:gen_merged_sql_metrics': [
+        [":cc_merged_sql_metrics"]
+    ]
+}
+
+
+def gen_sql_metrics(target):
+  label = BazelLabel(get_bazel_label_name(target.name), 'genrule')
+  label.srcs += [re.sub('^//', '', x) for x in target.inputs]
+  label.outs += target.outputs
+  label.cmd = r'$(location gen_merged_sql_metrics_py) --cpp_out=$@ $(SRCS)'
+  label.tools += [':gen_merged_sql_metrics_py']
+  return [label]
+
+
+custom_actions = {
+    '//src/trace_processor/metrics:gen_merged_sql_metrics': gen_sql_metrics,
+}
+
+# ------------------------------------------------------------------------------
+# End of configuration.
+# ------------------------------------------------------------------------------
+
+
+class Error(Exception):
+  pass
+
+
+class BazelLabel(object):
+
+  def __init__(self, name, type):
+    self.comment = None
+    self.name = name
+    self.type = type
+    self.visibility = []
+    self.srcs = []
+    self.hdrs = []
+    self.deps = []
+    self.external_deps = []
+    self.tools = []
+    self.outs = []
+
+  def __str__(self):
+    """Converts the object into a Bazel Starlark label."""
+    res = ''
+    res += ('# GN target: %s\n' % self.comment) if self.comment else ''
+    res += '%s(\n' % self.type
+    any_deps = len(self.deps) + len(self.external_deps) > 0
+    ORD = ['name', 'srcs', 'hdrs', 'visibility', 'deps', 'outs', 'cmd', 'tools']
+    key_sorter = lambda kv: ORD.index(kv[0]) if kv[0] in ORD else '99-' + kv[0]
+    for k, v in sorted(self.__dict__.iteritems(), key=key_sorter):
+      if k in ('type', 'comment',
+               'external_deps') or v is None or (v == [] and
+                                                 (k != 'deps' or not any_deps)):
+        continue
+      res += '    %s = ' % k
+      if isinstance(v, basestring):
+        res += '"%s",\n' % v
+      elif isinstance(v, list):
+        res += '[\n'
+        if k == 'deps' and len(self.external_deps) > 1:
+          indent = '           '
+        else:
+          indent = '    '
+        for entry in v:
+          res += '%s    "%s",\n' % (indent, entry)
+        res += '%s]' % indent
+        if k == 'deps' and self.external_deps:
+          res += ' + %s' % self.external_deps[0]
+          for edep in self.external_deps[1:]:
+            if isinstance(edep, list):
+              res += ' + [\n'
+              for inner_dep in edep:
+                res += '%s    "%s"\n' % (indent, inner_dep)
+              res += '    ]'
+            else:
+              res += ' +\n%s%s' % (indent, edep)
+        res += ',\n'
+      else:
+        raise Error('Unsupported value %s', type(v))
+    res += ')\n\n'
+    return res
+
+
+def get_bazel_label_name(gn_name):
+  """Converts a GN target name into a Bazel label name.
+
+  If target is in the public taraget list, returns only the GN target name,
+  e.g.: //src/ipc:perfetto_ipc -> perfetto_ipc
+
+  Otherwise, in the case of an intermediate taraget, returns a mangled path.
+  e.g.:  //include/perfetto/base:base -> include_perfetto_base_base.
+  """
+  if gn_name in default_targets:
+    return gn_utils.label_without_toolchain(gn_name).split(':')[1]
+  return gn_utils.label_to_target_name_with_path(gn_name)
+
+
+def gen_proto_labels(target):
+  """ Generates the xx_proto_library label for proto targets.
+
+  Bazel requires that each protobuf-related target is modeled with two labels:
+  1. A plugin-dependent target (e.g. cc_library, cc_protozero_library) that has
+     only a dependency on 2 and does NOT refer to any .proto sources.
+  2. A plugin-agnostic target that defines only the .proto sources and their
+     dependencies.
+  """
+  assert (target.type == 'proto_library')
+
+  def get_sources_label(target_name):
+    return re.sub('_(lite|zero)$', '',
+                  get_bazel_label_name(target_name)) + '_protos'
+
+  sources_label_name = get_sources_label(target.name)
+
+  # Generates 1.
+  if target.proto_plugin == 'proto':
+    plugin_label_type = 'perfetto_cc_proto_library'
+  elif target.proto_plugin == 'protozero':
+    plugin_label_type = 'perfetto_cc_protozero_library'
+  elif target.proto_plugin == 'ipc':
+    plugin_label_type = 'perfetto_cc_ipc_library'
+  else:
+    raise Error('Unknown proto plugin: %s' % target.proto_plugin)
+  plugin_label_name = get_bazel_label_name(target.name)
+  plugin_label = BazelLabel(plugin_label_name, plugin_label_type)
+  plugin_label.comment = target.name
+  plugin_label.deps += [':' + sources_label_name]
+
+  # Generates 2.
+  sources_label = BazelLabel(sources_label_name, 'perfetto_proto_library')
+  sources_label.comment = target.name
+  assert (all(x.startswith('//') for x in target.sources))
+  assert (all(x.endswith('.proto') for x in target.sources))
+  sources_label.srcs = sorted([x[2:] for x in target.sources])  # Strip //.
+  deps = [':' + get_sources_label(x) for x in target.proto_deps]
+  sources_label.deps = sorted(deps)
+
+  return [plugin_label, sources_label]
+
+
+def gen_target(gn_target):
+  if gn_target.type == 'proto_library':
+    return gen_proto_labels(gn_target)
+  elif gn_target.type == 'action':
+    if gn_target.name in custom_actions:
+      return custom_actions[gn_target.name](gn_target)
+    return []
+  elif gn_target.type == 'group':
+    return []
+  elif gn_target.type == 'executable':
+    bazel_type = 'perfetto_cc_binary'
+  elif gn_target.type == 'shared_library':
+    bazel_type = 'perfetto_cc_binary'
+    vars['linkshared'] = True
+  elif gn_target.type == 'static_library':
+    bazel_type = 'perfetto_cc_library'
+  elif gn_target.type == 'source_set':
+    bazel_type = 'filegroup'
+  else:
+    raise Error('target type not supported: %s' % gn_target.type)
+
+  label = BazelLabel(get_bazel_label_name(gn_target.name), bazel_type)
+  label.comment = gn_target.name
+  label.srcs = [x[2:] for x in gn_target.sources]
+
+  if gn_target.name in public_targets:
+    label.visibility = ['//visibility:public']
+
+  if gn_target.type in gn_utils.LINKER_UNIT_TYPES:
+    # |source_sets| contains the transitive set of source_set deps.
+    for trans_dep in gn_target.source_set_deps:
+      name = ':' + get_bazel_label_name(trans_dep)
+      if name.startswith(
+          ':include_perfetto_') and gn_target.type != 'executable':
+        label.hdrs += [name]
+      else:
+        label.srcs += [name]
+    for dep in gn_target.deps:
+      if dep.startswith('//gn:'):
+        assert (dep in external_deps), dep
+      if dep in external_deps:
+        assert (isinstance(external_deps[dep], list))
+        label.external_deps += external_deps[dep]
+      else:
+        label.deps += [':' + get_bazel_label_name(dep)]
+    label.deps += [':' + get_bazel_label_name(x) for x in gn_target.proto_deps]
+
+  # All items starting with : need to be sorted to the end of the list.
+  # However, Python makes specifying a comparator function hard so cheat
+  # instead and make everything start with : sort as if it started with |
+  # As | > all other normal ASCII characters, this will lead to all : targets
+  # starting with : to be sorted to the end.
+  label.srcs = sorted(label.srcs, key=lambda x: x.replace(':', '|'))
+
+  label.deps = sorted(label.deps)
+  label.hdrs = sorted(label.hdrs)
+  return [label]
+
+
+def gen_target_str(gn_target):
+  return ''.join(str(x) for x in gen_target(gn_target))
+
+
+def generate_build(gn_desc, targets, extras):
+  gn = gn_utils.GnParser(gn_desc)
+  res = '''
+# 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.
@@ -50,580 +313,95 @@
 # limitations under the License.
 #
 # This file is automatically generated by {}. Do not edit.
-""".format(__file__)
 
-# Arguments for the GN output directory.
-# host_os="linux" is to generate the right build files from Mac OS.
-gn_args = ' '.join([
-    'host_os="linux"',
-    'is_debug=false',
-    'is_perfetto_build_generator=true',
-    'target_os="linux"',
-])
+load("@perfetto_cfg//:perfetto_cfg.bzl", "PERFETTO_CONFIG")
+load(
+    "@perfetto//bazel:rules.bzl",
+    "perfetto_cc_binary",
+    "perfetto_cc_ipc_library",
+    "perfetto_cc_library",
+    "perfetto_cc_proto_library",
+    "perfetto_cc_protozero_library",
+    "perfetto_java_proto_library",
+    "perfetto_proto_library",
+    "perfetto_py_binary",
+    "perfetto_gensignature_internal_only",
+)
 
-# Default targets to translate to the blueprint file.
-default_targets = [
-  '//src/trace_processor:trace_processor_shell',
-  '//src/protozero:libprotozero',
-  '//src/trace_processor:trace_processor',
-  '//tools/trace_to_text:trace_to_text',
-  '//tools/trace_to_text:libpprofbuilder',
-  '//protos/perfetto/config:merged_config_gen',
-  '//protos/perfetto/trace:merged_trace_gen',
-  '//protos/perfetto/trace_processor:lite_gen',
-  '//protos/perfetto/metrics:lite_gen',
-]
+package(default_visibility = ["//visibility:private"])
 
-# The directory where the generated perfetto_build_flags.h will be copied into.
-buildflags_dir = 'include/perfetto/base/build_configs/bazel'
+licenses(["notice"])  # Apache 2.0
 
+exports_files(["NOTICE"])
+'''.format(__file__).lstrip()
 
-def enable_sqlite(module):
-  module.deps.add(Label('//third_party/sqlite'))
-  module.deps.add(Label('//third_party/sqlite:sqlite_ext_percentile'))
+  # Public targets need to be computed at the beginning (to figure out the
+  # intermediate deps) but printed at the end (because declaration order matters
+  # in Bazel).
+  public_str = ''
+  for target_name in sorted(public_targets):
+    target = gn.get_target(target_name)
+    public_str += gen_target_str(target)
 
+  res += '''
+# ##############################################################################
+# Internal targets
+# ##############################################################################
 
-def enable_jsoncpp(module):
-  module.deps.add(Label('//third_party/perfetto/google:jsoncpp'))
+'''.lstrip()
+  # Generate the other non-public targets.
+  for target_name in sorted(set(default_targets) - set(public_targets)):
+    target = gn.get_target(target_name)
+    res += gen_target_str(target)
 
+  # Generate all the intermediate targets.
+  for target in sorted(gn.all_targets.itervalues(), key=lambda x: x.name):
+    if target.name in default_targets or target.name in gn.proto_libs:
+      continue
+    res += gen_target_str(target)
 
-def enable_linenoise(module):
-  module.deps.add(Label('//third_party/perfetto/google:linenoise'))
+  res += '''
+# ##############################################################################
+# Proto libraries
+# ##############################################################################
 
+'''.lstrip()
+  # Force discovery of explicilty listed root proto targets.
+  for target_name in proto_targets:
+    gn.get_target(target_name)
 
-def enable_gtest_prod(module):
-  module.deps.add(Label('//third_party/perfetto/google:gtest_prod'))
+  # Generate targets for the transitive set of proto targets.
+  # TODO explain deduping here.
+  labels = {}
+  for target in gn.proto_libs.itervalues():
+    for label in gen_target(target):
+      labels[label.name] = label
 
+  res += ''.join(str(x) for x in labels.itervalues())
 
-def enable_protobuf_full(module):
-  module.deps.add(Label('//third_party/protobuf:libprotoc_legacy'))
-  module.deps.add(Label('//third_party/protobuf:protobuf_legacy'))
+  res += '''
+# ##############################################################################
+# Public targets
+# ##############################################################################
 
-
-def enable_perfetto_version(module):
-  module.deps.add(Label('//third_party/perfetto/google:perfetto_version'))
-
-
-def enable_zlib(module):
-  module.deps.add(Label('//third_party/zlib:zlibsystem'))
-
-
-def disable_module(module):
-  pass
-
-
-# Internal equivalents for third-party libraries that the upstream project
-# depends on.
-builtin_deps = {
-    '//buildtools:linenoise': enable_linenoise,
-    '//buildtools:protobuf_full': enable_protobuf_full,
-    '//buildtools:protobuf_lite': disable_module,
-    '//buildtools:protoc': disable_module,
-    '//buildtools:sqlite': enable_sqlite,
-    '//buildtools:zlib': enable_zlib,
-    '//gn:default_deps': disable_module,
-    '//gn:jsoncpp': enable_jsoncpp,
-    '//gn:protoc_lib': enable_protobuf_full,
-    '//gn/standalone:gen_git_revision': enable_perfetto_version,
-}
-
-# ----------------------------------------------------------------------------
-# End of configuration.
-# ----------------------------------------------------------------------------
-
-
-class Error(Exception):
-  pass
-
-
-def is_public_header(label):
-  """
-  Returns if this is a c++ header file that is part of the API.
-  Args:
-      label: Label to evaluate
-  """
-  # TODO(135923303): Remove the pprof builder once the long-term solution lands
-  return label.endswith('.h') and (
-    label.startswith('//include/perfetto/') or
-    label == '//tools/trace_to_text/pprof_builder.h' or
-    label == '//tools/trace_to_text/symbolizer.h')
-
-
-@functools.total_ordering
-class Label(object):
-  """Represents a label in BUILD file terminology. This class wraps a string
-  label to allow for correct comparision of labels for sorting.
-
-  Args:
-      label: The string rerepsentation of the label.
-  """
-
-  def __init__(self, label):
-    self.label = label
-
-  def is_absolute(self):
-    return self.label.startswith('//')
-
-  def dirname(self):
-    return self.label.split(':')[0] if ':' in self.label else self.label
-
-  def basename(self):
-    return self.label.split(':')[1] if ':' in self.label else ''
-
-  def __eq__(self, other):
-    return self.label == other.label
-
-  def __lt__(self, other):
-    return (
-        self.is_absolute(),
-        self.dirname(),
-        self.basename()
-    ) < (
-        other.is_absolute(),
-        other.dirname(),
-        other.basename()
-    )
-
-  def __str__(self):
-    return self.label
-
-  def __hash__(self):
-    return hash(self.label)
-
-
-class Writer(object):
-  def __init__(self, output, width=79):
-    self.output = output
-    self.width = width
-
-  def comment(self, text):
-    for line in textwrap.wrap(text,
-                              self.width - 2,
-                              break_long_words=False,
-                              break_on_hyphens=False):
-      self.output.write('# {}\n'.format(line))
-
-  def newline(self):
-    self.output.write('\n')
-
-  def line(self, s, indent=0):
-    self.output.write('    ' * indent + s + '\n')
-
-  def variable(self, key, value, sort=True):
-    if value is None:
-      return
-    if isinstance(value, set) or isinstance(value, list):
-      if len(value) == 0:
-        return
-      self.line('{} = ['.format(key), indent=1)
-      for v in sorted(list(value)) if sort else value:
-        self.line('"{}",'.format(v), indent=2)
-      self.line('],', indent=1)
-    elif isinstance(value, basestring):
-      self.line('{} = "{}",'.format(key, value), indent=1)
-    else:
-      self.line('{} = {},'.format(key, value), indent=1)
-
-  def header(self):
-    self.output.write(header)
-
-
-class Target(object):
-  """In-memory representation of a BUILD target."""
-
-  def __init__(self, type, name, gn_name=None):
-    assert type in ('cc_binary', 'cc_library', 'cc_proto_library',
-                    'proto_library', 'filegroup', 'alias',
-                    'pbzero_cc_proto_library', 'genrule',
-                    'transitive_descriptor_set', 'java_proto_library' )
-    self.type = type
-    self.name = name
-    self.srcs = set()
-    self.hdrs = set()
-    self.deps = set()
-    self.visibility = set()
-    self.gn_name = gn_name
-    self.cc_proto_fields = False
-    self.src_proto_library = None
-    self.outs = set()
-    self.cmd = None
-    self.tools = set()
-
-  def write(self, writer):
-    if self.gn_name:
-      writer.comment('GN target: {}'.format(self.gn_name))
-
-    writer.line('{}('.format(self.type))
-    writer.variable('name', self.name)
-    writer.variable('srcs', self.srcs)
-    writer.variable('hdrs', self.hdrs)
-
-    if self.cc_proto_fields:
-      assert(self.type == 'proto_library')
-      if self.srcs:
-        writer.variable('has_services', 1)
-      writer.variable('cc_api_version', 2)
-      if self.srcs:
-        writer.variable('cc_generic_services', 1)
-
-    writer.variable('src_proto_library', self.src_proto_library)
-
-    writer.variable('outs', self.outs)
-    writer.variable('cmd', self.cmd)
-    writer.variable('tools', self.tools)
-
-    # Keep visibility and deps last.
-    writer.variable('visibility', self.visibility)
-
-    if type != 'filegroup':
-      writer.variable('deps', self.deps)
-
-    writer.line(')')
-
-
-class Build(object):
-  """In-memory representation of a BUILD file."""
-
-  def __init__(self, public, header_lines=[]):
-    self.targets = {}
-    self.public = public
-    self.header_lines = header_lines
-
-  def add_target(self, target):
-    self.targets[target.name] = target
-
-  def write(self, writer):
-    writer.header()
-    writer.newline()
-    for line in self.header_lines:
-      writer.line(line)
-    if self.header_lines:
-      writer.newline()
-    if self.public:
-      writer.line(
-          'package(default_visibility = ["//visibility:public"])')
-    else:
-      writer.line(
-          'package(default_visibility = ["//third_party/perfetto:__subpackages__"])')
-    writer.newline()
-    writer.line('licenses(["notice"])  # Apache 2.0')
-    writer.newline()
-    writer.line('exports_files(["LICENSE"])')
-    writer.newline()
-
-    sorted_targets = sorted(
-        self.targets.itervalues(), key=lambda m: m.name)
-    for target in sorted_targets[:-1]:
-      target.write(writer)
-      writer.newline()
-
-    # BUILD files shouldn't have a trailing new line.
-    sorted_targets[-1].write(writer)
-
-
-class BuildGenerator(object):
-  def __init__(self, desc):
-    self.desc = desc
-    self.action_generated_files = set()
-
-    for target in self.desc.itervalues():
-      if target['type'] == 'action':
-        self.action_generated_files.update(target['outputs'])
-
-
-  def create_build_for_targets(self, targets):
-    """Generate a BUILD for a list of GN targets and aliases."""
-    self.build = Build(public=True)
-
-    proto_cc_import = 'load("//tools/build_defs/proto/cpp:cc_proto_library.bzl", "cc_proto_library")'
-    descriptor_set_import = 'load("//tools/build_defs/proto:descriptor_set.bzl", "transitive_descriptor_set")'
-    pbzero_cc_import = 'load("//third_party/perfetto/google:build_defs.bzl", "pbzero_cc_proto_library")'
-    self.proto_build = Build(public=False,
-                             header_lines=[
-                               proto_cc_import,
-                               descriptor_set_import,
-                               pbzero_cc_import,
-                             ])
-
-    for target in targets:
-      self.create_target(target)
-
-    return (self.build, self.proto_build)
-
-
-  def resolve_dependencies(self, target_name):
-    """Return the set of direct dependent-on targets for a GN target.
-
-    Args:
-        desc: JSON GN description.
-        target_name: Name of target
-
-    Returns:
-        A set of transitive dependencies in the form of GN targets.
-    """
-
-    if gn_utils.label_without_toolchain(target_name) in builtin_deps:
-      return set()
-    target = self.desc[target_name]
-    resolved_deps = set()
-    for dep in target.get('deps', []):
-      resolved_deps.add(dep)
-    return resolved_deps
-
-
-  def apply_module_sources_to_target(self, target, module_desc):
-    """
-    Args:
-        target: Module to which dependencies should be added.
-        module_desc: JSON GN description of the module.
-        visibility: Whether the module is visible with respect to the target.
-    """
-    for src in module_desc.get('sources', []):
-      label = Label(gn_utils.label_to_path(src))
-      if target.type == 'cc_library' and is_public_header(src):
-        target.hdrs.add(label)
-      else:
-        target.srcs.add(label)
-
-    if '//include/perfetto/base/build_config.h' in module_desc.get(
-        'sources', []):
-      label = Label(os.path.join(buildflags_dir, 'perfetto_build_flags.h'))
-      if target.type == 'cc_library':
-          target.hdrs.add(label)
-      elif target.type == 'cc_binary':
-        target.srcs.add(label)
-
-
-  def apply_module_dependency(self, target, dep_name):
-    """
-    Args:
-        build: BUILD instance which is being generated.
-        proto_build: BUILD instance which is being generated to hold protos.
-        desc: JSON GN description.
-        target: Module to which dependencies should be added.
-        dep_name: GN target of the dependency.
-    """
-    # If the dependency refers to a library which we can replace with an internal
-    # equivalent, stop recursing and patch the dependency in.
-    dep_name_no_toolchain = gn_utils.label_without_toolchain(dep_name)
-    if dep_name_no_toolchain in builtin_deps:
-      builtin_deps[dep_name_no_toolchain](target)
-      return
-
-    dep_desc = self.desc[dep_name]
-    if dep_desc['type'] == 'source_set':
-      for inner_name in self.resolve_dependencies(dep_name):
-        self.apply_module_dependency(target, inner_name)
-
-      # Any source set which has a source generated by an action doesn't need
-      # to be depended on as we will depend on the action directly.
-      sources = dep_desc.get('sources', [])
-      if any(src in self.action_generated_files for src in sources):
-        return
-
-      self.apply_module_sources_to_target(target, dep_desc)
-    elif dep_desc['type'] == 'action':
-      args = dep_desc['args']
-      if "gen_merged_sql_metrics" in dep_name:
-        dep_target = self.create_merged_sql_metrics_target(dep_name)
-        target.deps.add(Label("//third_party/perfetto:" + dep_target.name))
-
-        if target.type == 'cc_library' or target.type == 'cc_binary':
-          target.srcs.update(dep_target.outs)
-      elif '/protoc' in args[0]:
-        result = self.create_proto_target(dep_name);
-        if result is None:
-          return
-        (proto_target, cc_target) = result
-        if target.type == 'proto_library':
-          dep_target_name = proto_target.name
-        else:
-          dep_target_name = cc_target.name
-        target.deps.add(
-            Label("//third_party/perfetto/protos:" + dep_target_name))
-      else:
-        raise Error('Unsupported action in target %s: %s' % (dep_target_name,
-                                                            args))
-    elif dep_desc['type'] == 'static_library':
-      dep_target = self.create_target(dep_name)
-      target.deps.add(Label("//third_party/perfetto:" + dep_target.name))
-    elif dep_desc['type'] == 'group':
-      for inner_name in self.resolve_dependencies(dep_name):
-        self.apply_module_dependency(target, inner_name)
-    elif dep_desc['type'] == 'executable':
-      # Just create the dep target but don't add it as a dep because it's an
-      # executable.
-      self.create_target(dep_name)
-    else:
-      raise Error('Unknown target name %s with type: %s' %
-                  (dep_name, dep_desc['type']))
-
-  def create_merged_sql_metrics_target(self, gn_target_name):
-    target_desc = self.desc[gn_target_name]
-    gn_target_name_no_toolchain = gn_utils.label_without_toolchain(
-        gn_target_name)
-    target = Target(
-      'genrule',
-      'gen_merged_sql_metrics',
-      gn_name=gn_target_name_no_toolchain,
-    )
-    target.outs.update(
-      Label(src[src.index('gen/') + len('gen/'):])
-      for src in target_desc.get('outputs', [])
-    )
-    target.cmd = '$(location gen_merged_sql_metrics_py) --cpp_out=$@ $(SRCS)'
-    target.tools.update([
-      'gen_merged_sql_metrics_py',
-    ])
-    target.srcs.update(
-      Label(gn_utils.label_to_path(src))
-      for src in target_desc.get('inputs', [])
-      if src not in self.action_generated_files
-    )
-    self.build.add_target(target)
-    return target
-
-  def create_proto_target(self, gn_target_name):
-    target_desc = self.desc[gn_target_name]
-    args = target_desc['args']
-
-    gn_target_name_no_toolchain = gn_utils.label_without_toolchain(
-        gn_target_name)
-    stripped_path = gn_target_name_no_toolchain.replace("protos/perfetto/", "")
-
-    is_descriptor = any('descriptor_set_out' in arg for arg in args)
-    if is_descriptor:
-      return None
-
-    is_pbzero = any("pbzero" in arg for arg in args)
-    is_proto_lite = not is_pbzero and not is_descriptor
-
-    pretty_target_name = gn_utils.label_to_target_name_with_path(stripped_path)
-    pretty_target_name = pretty_target_name.replace("_lite_gen", "")
-    pretty_target_name = pretty_target_name.replace("_zero_gen", "_zero")
-    proto_target_name = pretty_target_name
-
-    proto_target = Target(
-      'proto_library',
-      proto_target_name,
-      gn_name=gn_target_name_no_toolchain
-    )
-    proto_target.cc_proto_fields = is_proto_lite
-    proto_target.srcs.update([
-      Label(gn_utils.label_to_path(src).replace('protos/', ''))
-      for src in target_desc.get('sources', [])
-    ])
-    if is_proto_lite:
-      proto_target.visibility.add("//visibility:public")
-    self.proto_build.add_target(proto_target)
-
-    for dep_name in self.resolve_dependencies(gn_target_name):
-      self.apply_module_dependency(proto_target, dep_name)
-
-    if is_pbzero:
-      # Remove all the protozero srcs from the proto_library.
-      proto_target.srcs.difference_update(
-          [src for src in proto_target.srcs if not src.label.endswith('.proto')])
-
-      # Remove all the non-proto deps from the proto_library and add to the cc
-      # library.
-      cc_deps = [
-        dep for dep in proto_target.deps
-        if not dep.label.startswith('//third_party/perfetto/protos')
-      ]
-      proto_target.deps.difference_update(cc_deps)
-
-      cc_target_name = proto_target.name + "_cc_proto"
-      cc_target = Target('pbzero_cc_proto_library', cc_target_name,
-                         gn_name=gn_target_name_no_toolchain)
-
-      cc_target.deps.add(Label('//third_party/perfetto:libprotozero'))
-      cc_target.deps.update(cc_deps)
-
-      # Add the proto_library to the cc_target.
-      cc_target.src_proto_library = \
-          "//third_party/perfetto/protos:" + proto_target.name
-
-      self.proto_build.add_target(cc_target)
-    else:
-      cc_target_name = proto_target.name + "_cc_proto"
-      cc_target = Target('cc_proto_library',
-                        cc_target_name, gn_name=gn_target_name_no_toolchain)
-      cc_target.visibility.add("//visibility:public")
-      cc_target.deps.add(
-          Label("//third_party/perfetto/protos:" + proto_target.name))
-      self.proto_build.add_target(cc_target)
-
-      java_target_name = proto_target.name + "_java_proto"
-      java_target = Target('java_proto_library',
-                           java_target_name,
-                           gn_name=gn_target_name_no_toolchain)
-      java_target.visibility.add("//visibility:public")
-      java_target.deps.add(
-          Label("//third_party/perfetto/protos:" + proto_target.name))
-      self.proto_build.add_target(java_target)
-
-    return (proto_target, cc_target)
-
-
-  def create_target(self, gn_target_name):
-    """Generate module(s) for a given GN target.
-
-    Given a GN target name, generate one or more corresponding modules into a
-    build file.
-
-    Args:
-        build: Build instance which is being generated.
-        desc: JSON GN description.
-        gn_target_name: GN target name for module generation.
-    """
-
-    target_desc = self.desc[gn_target_name]
-    if target_desc['type'] == 'action':
-      args = target_desc['args']
-      if '/protoc' in args[0]:
-        return self.create_proto_target(gn_target_name)
-      else:
-        raise Error('Unsupported action in target %s: %s' % (gn_target_name,
-                                                            args))
-    elif target_desc['type'] == 'executable':
-      target_type = 'cc_binary'
-    elif target_desc['type'] == 'static_library':
-      target_type = 'cc_library'
-    elif target_desc['type'] == 'source_set':
-      target_type = 'filegroup'
-    else:
-      raise Error('Unknown target type: %s' % target_desc['type'])
-
-    label_no_toolchain = gn_utils.label_without_toolchain(gn_target_name)
-    target_name_path = gn_utils.label_to_target_name_with_path(label_no_toolchain)
-    if label_no_toolchain in default_targets:
-        target_name = label_no_toolchain.split(':')[-1]
-    else:
-      target_name = target_name_path
-    target = Target(target_type, target_name, gn_name=label_no_toolchain)
-    target.srcs.update(
-        Label(gn_utils.label_to_path(src))
-        for src in target_desc.get('sources', [])
-        if src not in self.action_generated_files
-    )
-
-    for dep_name in self.resolve_dependencies(gn_target_name):
-      self.apply_module_dependency(target, dep_name)
+'''.lstrip()
+  res += public_str
+  res += '# Content from BUILD.extras\n\n'
+  res += extras
+  return res
 
-    self.build.add_target(target)
-    return target
 
 def main():
   parser = argparse.ArgumentParser(
       description='Generate BUILD from a GN description.')
   parser.add_argument(
-        '--check-only', help='Don\'t keep the generated files',
-        action='store_true')
+      '--check-only',
+      help='Don\'t keep the generated files',
+      action='store_true')
   parser.add_argument(
       '--desc',
-      help='GN description (e.g., gn desc out --format=json --all-toolchains "//*"'
-  )
+      help='GN description ' +
+      '(e.g., gn desc out --format=json --all-toolchains "//*"')
   parser.add_argument(
       '--repo-root',
       help='Standalone Perfetto repository to generate a GN description',
@@ -658,24 +436,14 @@
 
   out_files = []
 
-  build_generator = BuildGenerator(desc)
-  build, proto_build = build_generator.create_build_for_targets(
-      args.targets or default_targets)
-
   # Generate the main BUILD file.
-  out_files.append(args.output + '.swp')
-  with open(out_files[-1], 'w') as f:
-    writer = Writer(f)
-    build.write(writer)
-    writer.newline()
-    with open(args.extras, 'r') as r:
-      for line in r:
-        writer.line(line.rstrip("\n\r"))
+  with open(args.extras, 'r') as extra_f:
+    extras = extra_f.read()
 
-  # Generate the protos/BUILD file.
-  out_files.append(args.output_proto + '.swp')
-  with open(out_files[-1], 'w') as f:
-    proto_build.write(Writer(f))
+  contents = generate_build(desc, args.targets or default_targets, extras)
+  out_files.append(args.output + '.swp')
+  with open(out_files[-1], 'w') as out_f:
+    out_f.write(contents)
 
   # Generate the build flags file.
   out_files.append(os.path.join(buildflags_dir, 'perfetto_build_flags.h.swp'))
diff --git a/tools/gen_merged_sql_metrics.py b/tools/gen_merged_sql_metrics.py
index cb36db5..319d0d3 100755
--- a/tools/gen_merged_sql_metrics.py
+++ b/tools/gen_merged_sql_metrics.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python
 # Copyright (C) 2019 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -104,8 +104,7 @@
     for path in sql_outputs.keys():
       name = os.path.basename(path)
       variable = filename_to_variable(os.path.splitext(name)[0])
-      path_escaped = path.encode('string_escape')
-      output.write('\n  {{"{}", {}}},\n'.format(path_escaped, variable))
+      output.write('\n  {{"{}", {}}},\n'.format(path, variable))
     output.write("};\n")
 
     output.write(NAMESPACE_END)
diff --git a/tools/gn_utils.py b/tools/gn_utils.py
index 30c646b..1bc7afc 100644
--- a/tools/gn_utils.py
+++ b/tools/gn_utils.py
@@ -27,6 +27,7 @@
 
 
 BUILDFLAGS_TARGET = '//gn:gen_buildflags'
+LINKER_UNIT_TYPES = ('executable', 'shared_library', 'static_library')
 
 
 def _check_command_output(cmd, cwd):
@@ -183,4 +184,182 @@
             os.unlink(tmp_file)
         else:
             os.rename(tmp_file, target_file)
-    return res
\ No newline at end of file
+    return res
+
+
+class GnParser(object):
+    """A parser with some cleverness for GN json desc files
+
+    The main goals of this parser are:
+    1) Deal with the fact that other build systems don't have an equivalent
+       notion to GN's source_set. Conversely to Bazel's and Soong's filegroups,
+       GN source_sets expect that dependencies, cflags and other source_set
+       properties propagate up to the linker unit (static_library, executable or
+       shared_library). This parser simulates the same behavior: when a
+       source_set is encountered, some of its variables (cflags and such) are
+       copied up to the dependent targets. This is to allow gen_xxx to create
+       one filegroup for each source_set and then squash all the other flags
+       onto the linker unit.
+    2) Detect and special-case protobuf targets, figuring out the protoc-plugin
+       being used.
+    """
+    class Target(object):
+        """Reperesents A GN target.
+
+        Maked properties are propagated up the dependency chain when a
+        source_set dependency is encountered.
+        """
+        def __init__(self, name, type):
+            self.name = name  # e.g. //src/ipc:ipc
+
+            VALID_TYPES = ('static_library', 'shared_library', 'executable',
+                           'group', 'action', 'source_set', 'proto_library')
+            assert(type in VALID_TYPES)
+            self.type = type
+
+            # Only set when type == proto_library.
+            # This is typically: 'proto', 'protozero', 'ipc'.
+            self.proto_plugin = None
+
+            self.sources = set()
+
+            # These are valid only for type == 'action'
+            self.inputs = set()
+            self.outputs = set()
+            self.script = None
+            self.args = []
+
+            # These variables are propagated up when encountering a dependency
+            # on a source_set target.
+            self.cflags = set()
+            self.defines = set()
+            self.deps = set()
+            self.include_dirs = set()
+            self.ldflags = set()
+            self.source_set_deps = set()  # Transitive set of source_set deps.
+            self.proto_deps = set()  # Transitive set of protobuf deps.
+
+            # Deps on //gn:xxx have this flag set to True. These dependencies
+            # are special because they pull third_party code from buildtools/.
+            # We don't want to keep recursing into //buildtools in generators,
+            # this flag is used to stop the recursion and create an empty
+            # placeholder target once we hit //gn:protoc or similar.
+            self.is_third_party_dep_ = False
+
+        def __repr__(self):
+            return json.dumps({k:(list(v) if isinstance(v, set) else v)
+                    for (k,v) in self.__dict__.iteritems()}, indent=4)
+
+        def update(self, other):
+            for key in ('cflags', 'defines', 'deps', 'include_dirs', 'ldflags',
+                        'source_set_deps', 'proto_deps'):
+                self.__dict__[key].update(other.__dict__.get(key, []))
+
+
+    def __init__(self, gn_desc):
+        self.gn_desc_ = gn_desc
+        self.all_targets = {}
+        self.linker_units = {}  # Executables, shared or static libraries.
+        self.source_sets = {}
+        self.actions = {}
+        self.proto_libs = {}
+
+
+    def get_target(self, gn_target_name):
+        """Returns a Target object from the fully qualified GN target name.
+
+        It bubbles up variables from source_set dependencies as described in the
+        class-level comments.
+        """
+        target = self.all_targets.get(gn_target_name)
+        if target is not None:
+            return target  # Taraget already processed.
+
+        desc = self.gn_desc_[gn_target_name]
+        target = GnParser.Target(gn_target_name, desc['type'])
+        self.all_targets[gn_target_name] = target
+
+        # We should never have GN targets directly depend on buidtools. They
+        # should hop via //gn:xxx, so we can give generators an opportunity to
+        # override them.
+        assert(not gn_target_name.startswith('//buildtools'))
+
+        # Don't descend further into third_party targets. Genrators are supposed
+        # to either ignore them or route to other externally-provided targets.
+        if gn_target_name.startswith('//gn'):
+            target.is_third_party_dep_ = True
+            return target
+
+        proto_target_type = self.get_proto_target_type_(target)
+        if proto_target_type is not None:
+            self.proto_libs[target.name] = target
+            target.type = 'proto_library'
+            target.proto_plugin = proto_target_type
+            proto_desc = self.gn_desc_[target.name + '_gen']
+            target.sources.update(proto_desc.get('sources', []))
+            assert(all(x.endswith('.proto') for x in target.sources))
+        elif target.type == 'source_set':
+            self.source_sets[gn_target_name] = target
+            target.sources.update(desc.get('sources', []))
+        elif target.type in LINKER_UNIT_TYPES:
+            self.linker_units[gn_target_name] = target
+            target.sources.update(desc.get('sources', []))
+        elif target.type == 'action':
+            self.actions[gn_target_name] = target
+            target.inputs.update(desc['inputs'])
+            outs = [re.sub('^//out/[^/]+/gen/', '', x) for x in desc['outputs']]
+            target.outputs.update(outs)
+            target.script = desc['script']
+            # Args are typically relative to the root build dir (../../xxx)
+            # because root build dir is typically out/xxx/).
+            target.args = [re.sub('^../../', '//', x) for x in desc['args']]
+
+        target.cflags.update(desc.get('cflags', []) + desc.get('cflags_cc', []))
+        target.ldflags.update(desc.get('ldflags', []))
+        target.defines.update(desc.get('defines', []))
+        target.include_dirs.update(desc.get('include_dirs', []))
+
+        # Recurse in dependencies.
+        for dep_name in desc.get('deps', []):
+            dep = self.get_target(dep_name)
+            if dep.is_third_party_dep_:
+                target.deps.add(dep_name)
+            elif dep.type == 'proto_library':
+                target.proto_deps.add(dep_name)
+                target.proto_deps.update(dep.proto_deps)  # Bubble up deps.
+            elif dep.type == 'source_set':
+                target.source_set_deps.add(dep_name)
+                target.update(dep)  # Bubble up source set's cflags/ldflags etc.
+            elif dep.type == 'group':
+                target.update(dep)  # Bubble up groups's cflags/ldflags etc.
+            elif dep.type == 'action':
+                target.deps.add(dep_name)
+            elif dep.type in LINKER_UNIT_TYPES:
+                target.deps.add(dep_name)
+
+        return target
+
+    def get_proto_target_type_(self, target):
+        """ Checks if the target is a proto library and return the plugin.
+
+        Returns:
+            None: if the target is not a proto library.
+            The plugin name (or 'proto' in the default case) for proto library
+            targets.
+        """
+        gen_desc = self.gn_desc_.get(target.name + '_gen')
+        if gen_desc is None or gen_desc['type'] != 'action':
+            return None
+        args = gen_desc.get('args', [])
+        if '/protoc' not in args[0]:
+            return None
+        for arg in args:
+            if arg.startswith('--plugin='):
+                # |arg| at this point looks like:
+                #  --plugin=protoc-gen-plugin=gcc_like_host/protozero_plugin
+                # or
+                #  --plugin=protoc-gen-plugin=protozero_plugin
+                return arg.split('=')[-1].split('/')[-1].replace('_plugin', '')
+        return 'proto'
+
+
diff --git a/tools/trace_to_text/BUILD.gn b/tools/trace_to_text/BUILD.gn
index 5cd2e36..5272085 100644
--- a/tools/trace_to_text/BUILD.gn
+++ b/tools/trace_to_text/BUILD.gn
@@ -46,6 +46,7 @@
     "../../protos/perfetto/trace/ftrace:lite",
     "../../protos/perfetto/trace/interned_data:lite",
     "../../protos/perfetto/trace/profiling:lite",
+    "../../src/trace_processor:lib",
   ]
   sources = [
     "profile_visitor.cc",
@@ -104,6 +105,7 @@
     "../../protos/perfetto/trace/profiling:lite",
     "../../protos/third_party/pprof:lite",
     "../../src/base",
+    "../../src/trace_processor:lib",
   ]
   sources = [
     "pprof_builder.cc",
diff --git a/tools/trace_to_text/trace_to_systrace.cc b/tools/trace_to_text/trace_to_systrace.cc
index e67ef09..c987165 100644
--- a/tools/trace_to_text/trace_to_systrace.cc
+++ b/tools/trace_to_text/trace_to_systrace.cc
@@ -31,6 +31,7 @@
 #include "perfetto/ext/base/string_writer.h"
 #include "perfetto/ext/base/utils.h"
 #include "perfetto/trace_processor/trace_processor.h"
+#include "tools/trace_to_text/utils.h"
 
 // When running in Web Assembly, fflush() is a no-op and the stdio buffering
 // sends progress updates to JS only when a write ends with \n.
@@ -180,42 +181,8 @@
   std::unique_ptr<trace_processor::TraceProcessor> tp =
       trace_processor::TraceProcessor::CreateInstance(config);
 
-  // 1MB chunk size seems the best tradeoff on a MacBook Pro 2013 - i7 2.8 GHz.
-  constexpr size_t kChunkSize = 1024 * 1024;
-
-// Printing the status update on stderr can be a perf bottleneck. On WASM print
-// status updates more frequently because it can be slower to parse each chunk.
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
-  constexpr int kStderrRate = 1;
-#else
-  constexpr int kStderrRate = 128;
-#endif
-  uint64_t file_size = 0;
-
-  for (int i = 0;; i++) {
-    if (i % kStderrRate == 0) {
-      fprintf(stderr, "Loading trace %.2f MB" PROGRESS_CHAR, file_size / 1.0e6);
-      fflush(stderr);
-    }
-
-    std::unique_ptr<uint8_t[]> buf(new uint8_t[kChunkSize]);
-    input->read(reinterpret_cast<char*>(buf.get()), kChunkSize);
-    if (input->bad()) {
-      PERFETTO_ELOG("Failed when reading trace");
-      return 1;
-    }
-
-    auto rsize = input->gcount();
-    if (rsize <= 0)
-      break;
-    file_size += static_cast<uint64_t>(rsize);
-    tp->Parse(std::move(buf), static_cast<size_t>(rsize));
-  }
-  tp->NotifyEndOfFile();
-
-  fprintf(stderr, "Loaded trace" PROGRESS_CHAR);
-  fflush(stderr);
-
+  if (!ReadTrace(tp.get(), input))
+    return 1;
   using Iterator = trace_processor::TraceProcessor::Iterator;
 
   QueryWriter q_writer(tp.get(), output);
diff --git a/tools/trace_to_text/utils.cc b/tools/trace_to_text/utils.cc
index f6254a1..6813df1 100644
--- a/tools/trace_to_text/utils.cc
+++ b/tools/trace_to_text/utils.cc
@@ -105,5 +105,45 @@
   return roots;
 }
 
+bool ReadTrace(trace_processor::TraceProcessor* tp, std::istream* input) {
+  // 1MB chunk size seems the best tradeoff on a MacBook Pro 2013 - i7 2.8 GHz.
+  constexpr size_t kChunkSize = 1024 * 1024;
+
+// Printing the status update on stderr can be a perf bottleneck. On WASM print
+// status updates more frequently because it can be slower to parse each chunk.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
+  constexpr int kStderrRate = 1;
+#else
+  constexpr int kStderrRate = 128;
+#endif
+  uint64_t file_size = 0;
+
+  for (int i = 0;; i++) {
+    if (i % kStderrRate == 0) {
+      fprintf(stderr, "Loading trace %.2f MB%c", file_size / 1.0e6,
+              kProgressChar);
+      fflush(stderr);
+    }
+
+    std::unique_ptr<uint8_t[]> buf(new uint8_t[kChunkSize]);
+    input->read(reinterpret_cast<char*>(buf.get()), kChunkSize);
+    if (input->bad()) {
+      PERFETTO_ELOG("Failed when reading trace");
+      return false;
+    }
+
+    auto rsize = input->gcount();
+    if (rsize <= 0)
+      break;
+    file_size += static_cast<uint64_t>(rsize);
+    tp->Parse(std::move(buf), static_cast<size_t>(rsize));
+  }
+  tp->NotifyEndOfFile();
+
+  fprintf(stderr, "Loaded trace%c", kProgressChar);
+  fflush(stderr);
+  return true;
+}
+
 }  // namespace trace_to_text
 }  // namespace perfetto
diff --git a/tools/trace_to_text/utils.h b/tools/trace_to_text/utils.h
index dd2d24c..729d902 100644
--- a/tools/trace_to_text/utils.h
+++ b/tools/trace_to_text/utils.h
@@ -27,6 +27,7 @@
 #include <vector>
 
 #include "perfetto/base/build_config.h"
+#include "perfetto/trace_processor/trace_processor.h"
 
 namespace perfetto {
 
@@ -54,6 +55,8 @@
 
 std::vector<std::string> GetPerfettoBinaryPath();
 
+bool ReadTrace(trace_processor::TraceProcessor* tp, std::istream* input);
+
 }  // namespace trace_to_text
 }  // namespace perfetto
 
diff --git a/ui/BUILD.gn b/ui/BUILD.gn
index 5c0a988..c53171b 100644
--- a/ui/BUILD.gn
+++ b/ui/BUILD.gn
@@ -201,6 +201,7 @@
   inputs += [
     "../protos/perfetto/config/perfetto_config.proto",
     "../protos/perfetto/ipc/consumer_port.proto",
+    "../protos/perfetto/ipc/wire_protocol.proto",
   ]
   outputs = [
     "$ui_gen_dir/protos.js",
diff --git a/ui/src/assets/common.scss b/ui/src/assets/common.scss
index 6182663..1acf957 100644
--- a/ui/src/assets/common.scss
+++ b/ui/src/assets/common.scss
@@ -72,6 +72,7 @@
     padding: 0;
     margin: 0;
     user-select: none;
+    overscroll-behavior: none;
 }
 
 h1,
diff --git a/ui/src/assets/record.scss b/ui/src/assets/record.scss
index 8c7a840..b1aea32 100644
--- a/ui/src/assets/record.scss
+++ b/ui/src/assets/record.scss
@@ -22,6 +22,7 @@
 
 // The always-visible centered box that has menu and sections on the right.
 .record-container {
+  position: relative;
   max-width: 900px;
   min-height: 500px;
   margin: auto;
@@ -34,6 +35,19 @@
   grid-template-areas: "header header"
                        "sidebar section";
   overflow: hidden;
+  z-index: 6;
+}
+
+.hider {
+  @include transition(0.2s);
+  position: fixed;
+  left: 0;
+  top: 0;
+  bottom: 0;
+  right: 0;
+  background: #000;
+  opacity: 0.2;
+  z-index: 5;
 }
 
 .record-header {
@@ -242,6 +256,11 @@
       }
     }
   }  // li
+
+  &.disabled {
+    opacity: 0.50;
+    pointer-events: none;
+  }
 }  // record-menu
 
 
diff --git a/ui/src/assets/topbar.scss b/ui/src/assets/topbar.scss
index 2e3fee9..b3902bb 100644
--- a/ui/src/assets/topbar.scss
+++ b/ui/src/assets/topbar.scss
@@ -117,6 +117,9 @@
             grid-area: help;
             overflow: visible;
             padding-left: 5px;
+            &:hover {
+              cursor: pointer;
+            }
             .material-icons {
                 color: #bdbdbd;
                 font-size: 16px;
diff --git a/ui/src/base/string_utils.ts b/ui/src/base/string_utils.ts
index 0ad7dd3..efe8fb0 100644
--- a/ui/src/base/string_utils.ts
+++ b/ui/src/base/string_utils.ts
@@ -16,6 +16,10 @@
   return btoa(uint8ArrayToString(buffer));
 }
 
+// This function will not handle correctly buffers with a large number of
+// elements due to a js limitation on the number of arguments of a function.
+// The apply will in fact do a call like
+// 'String.fromCharCode(buffer[0],buffer[1],...)'.
 export function uint8ArrayToString(buffer: Uint8Array): string {
   return String.fromCharCode.apply(null, Array.from(buffer));
 }
diff --git a/ui/src/chrome_extension/chrome_tracing_controller.ts b/ui/src/chrome_extension/chrome_tracing_controller.ts
index d46f6b7..93b5f01 100644
--- a/ui/src/chrome_extension/chrome_tracing_controller.ts
+++ b/ui/src/chrome_extension/chrome_tracing_controller.ts
@@ -28,7 +28,9 @@
 
 import {DevToolsSocket} from './devtools_socket';
 
-const CHUNK_SIZE: number = 1024 * 1024 * 64;
+// The chunk size should be large enough to support reasonable batching of data,
+// but small enough not to cause stack overflows in uint8ArrayToString().
+const CHUNK_SIZE: number = 1024 * 1024 * 16;  // 16Mb
 
 export class ChromeTracingController extends RpcConsumerPort {
   private streamHandle: string|undefined = undefined;
@@ -126,12 +128,12 @@
     if (res === undefined) return;
 
     const chunk = res.base64Encoded ? atob(res.data) : res.data;
-    // TODO(nicomazz): remove the conversion to unknown when we stream each
-    // chunk to the trace processor.
+    // The 'as {} as UInt8Array' is done because we can't send ArrayBuffers
+    // trough a chrome.runtime.Port. The conversion from string to ArrayBuffer
+    // takes place on the other side of the port.
     const response: ReadBuffersResponse = {
       type: 'ReadBuffersResponse',
-      slices:
-          [{data: chunk as unknown as Uint8Array, lastSliceForPacket: res.eof}]
+      slices: [{data: chunk as {} as Uint8Array, lastSliceForPacket: res.eof}]
     };
     this.sendMessage(response);
     if (res.eof) return;
diff --git a/ui/src/common/actions.ts b/ui/src/common/actions.ts
index bd78842..ef855f7 100644
--- a/ui/src/common/actions.ts
+++ b/ui/src/common/actions.ts
@@ -26,6 +26,7 @@
   SCROLLING_TRACK_GROUP,
   State,
   Status,
+  TargetOs,
   TraceTime,
   TrackState,
   VisibleState,
@@ -46,11 +47,19 @@
   const nextId = state.nextId;
   const recordConfig = state.recordConfig;
   const route = state.route;
+  const androidDeviceConnected = state.androidDeviceConnected;
+  const extensionInstalled = state.extensionInstalled;
+  const availableDevices = state.availableDevices;
+  const chromeCategories = state.chromeCategories;
 
   Object.assign(state, createEmptyState());
   state.nextId = nextId;
   state.recordConfig = recordConfig;
   state.route = route;
+  state.androidDeviceConnected = androidDeviceConnected;
+  state.extensionInstalled = extensionInstalled;
+  state.availableDevices = availableDevices;
+  state.chromeCategories = chromeCategories;
 }
 
 export const StateActions = {
@@ -442,6 +451,8 @@
 
   setAndroidDevice(state: StateDraft, args: {target?: AdbRecordingTarget}):
       void {
+        state.recordConfig.targetOS =
+            args.target ? args.target.os as TargetOs : 'Q';
         state.androidDeviceConnected = args.target;
       },
 
diff --git a/ui/src/common/time.ts b/ui/src/common/time.ts
index 5a92f81..fce992d 100644
--- a/ui/src/common/time.ts
+++ b/ui/src/common/time.ts
@@ -107,4 +107,8 @@
   add(sec: number): TimeSpan {
     return new TimeSpan(this.start + sec, this.end + sec);
   }
+
+  contains(other: TimeSpan) {
+    return this.start <= other.start && other.end <= this.end;
+  }
 }
diff --git a/ui/src/controller/adb.ts b/ui/src/controller/adb.ts
index 6ba9515..3bbaa37 100644
--- a/ui/src/controller/adb.ts
+++ b/ui/src/controller/adb.ts
@@ -75,6 +75,11 @@
   }
 
   async connect(device: USBDevice): Promise<void> {
+    if (this.state === AdbState.CONNECTED && this.dev === device) {
+      this.onConnected();
+      this.onConnected = () => {};
+      return;
+    }
     this.dev = device;
     this.useChecksum = true;
     this.key = await AdbOverWebUsb.initKey();
@@ -243,6 +248,10 @@
     return this.openStream('shell:' + cmd);
   }
 
+  socket(path: string): Promise<AdbStream> {
+    return this.openStream('localfilesystem:' + path);
+  }
+
   openStream(svc: string): Promise<AdbStream> {
     const stream = new AdbStreamImpl(this, ++this.lastStreamId);
     this.streams.set(stream.localStreamId, stream);
@@ -260,7 +269,7 @@
 
     return new Promise<string>((resolve, _) => {
       const output: string[] = [];
-      shell.onData = (str, _) => output.push(str);
+      shell.onData = raw => output.push(textDecoder.decode(raw));
       shell.onClose = () => resolve(output.join());
     });
   }
@@ -361,7 +370,7 @@
 
   private sendInProgress = false;
 
-  onData: AdbStreamReadCallback = (_, __) => {};
+  onData: AdbStreamReadCallback = (_) => {};
   onConnect = () => {};
   onClose = () => {};
 
@@ -413,7 +422,7 @@
 
     if (msg.cmd === 'WRTE') {
       this.adb.send('OKAY', this.localStreamId, this.remoteStreamId);
-      this.onData(msg.dataStr, msg.data);
+      this.onData(msg.data);
       return;
     }
 
@@ -435,7 +444,7 @@
 }
 
 interface AdbStreamReadCallback {
-  (str: string, raw: Uint8Array): void;
+  (raw: Uint8Array): void;
 }
 
 const ADB_MSG_SIZE = 6 * 4;  // 6 * int32.
diff --git a/ui/src/controller/adb_interfaces.ts b/ui/src/controller/adb_interfaces.ts
index 2f22a2f..175ba5a 100644
--- a/ui/src/controller/adb_interfaces.ts
+++ b/ui/src/controller/adb_interfaces.ts
@@ -16,17 +16,22 @@
 export interface Adb {
   connect(device: USBDevice): Promise<void>;
   disconnect(): Promise<void>;
+  // Executes a shell command non-interactively.
   shell(cmd: string): Promise<AdbStream>;
+  // Waits until the shell get closed, and returns all the output.
   shellOutputAsString(cmd: string): Promise<string>;
+  // Opens a connection to a UNIX socket.
+  socket(path: string): Promise<AdbStream>;
 }
 
 export interface AdbStream {
+  write(msg: string|Uint8Array): Promise<void>;
   onMessage(message: AdbMsg): void;
-  onData: (str: string, raw: Uint8Array) => void;
   close(): void;
 
   onConnect: VoidCallback;
   onClose: VoidCallback;
+  onData: (raw: Uint8Array) => void;
 }
 
 export class MockAdb implements Adb {
@@ -45,14 +50,22 @@
   shellOutputAsString(_: string): Promise<string> {
     return Promise.resolve('');
   }
+
+  socket(_: string): Promise<AdbStream> {
+    return Promise.resolve(new MockAdbStream());
+  }
 }
 
 export class MockAdbStream implements AdbStream {
-  onData = (_: string, __: Uint8Array) => {};
-  onConnect = () => {};
-  onClose = () => {};
+  write(_: string|Uint8Array): Promise<void> {
+    return Promise.resolve();
+  }
   onMessage = (_: AdbMsg) => {};
   close() {}
+
+  onConnect = () => {};
+  onClose = () => {};
+  onData = (_: Uint8Array) => {};
 }
 
 export declare type CmdType =
diff --git a/ui/src/controller/adb_record_controller.ts b/ui/src/controller/adb_record_controller.ts
index 990053d..f52714d 100644
--- a/ui/src/controller/adb_record_controller.ts
+++ b/ui/src/controller/adb_record_controller.ts
@@ -12,6 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+import {_TextDecoder} from 'custom_utils';
 import {uint8ArrayToBase64} from '../base/string_utils';
 
 import {Adb, AdbStream} from './adb_interfaces';
@@ -29,6 +30,7 @@
   FETCHING
 }
 const DEFAULT_DESTINATION_FILE = '/data/misc/perfetto-traces/trace';
+const textDecoder = new _TextDecoder();
 
 export class AdbConsumerPort extends RpcConsumerPort {
   // public for testing
@@ -38,8 +40,8 @@
   private device: USBDevice|undefined = undefined;
   private recordShell?: AdbStream;
 
-  constructor(adb: Adb, consumerPortListener: Consumer) {
-    super(consumerPortListener);
+  constructor(adb: Adb, consumer: Consumer) {
+    super(consumer);
     this.adb = adb;
   }
 
@@ -96,7 +98,7 @@
     const recordCommand = this.generateStartTracingCommand(configProto);
     this.recordShell = await this.adb.shell(recordCommand);
     const output: string[] = [];
-    this.recordShell.onData = (str, _) => output.push(str);
+    this.recordShell.onData = raw => output.push(textDecoder.decode(raw));
     this.recordShell.onClose = () => {
       const response = output.join();
       if (!this.tracingEndedSuccessfully(response)) {
@@ -126,24 +128,12 @@
 
     const readTraceShell =
         await this.adb.shell(this.generateReadTraceCommand());
-    let trace = '';
-    readTraceShell.onData = (str, _) => {
-      // TODO(nicomazz): Since we are using base64, we can't decode the chunks
-      // as they are received (without further base64 stream decoding
-      // implementations). After the investigation about why without base64
-      // things are not working, the chunks should be sent as they are received,
-      // like in the following line.
-      // this.sendMessage(this.generateChunkReadResponse(str));
-      // EDIT: we should send back a response as if it was a real
-      // ReadBufferResponse, with trace packets. Here we are only sending the
-      // trace split in several pieces.
-      trace += str;
-    };
-    readTraceShell.onClose = () => {
-      const decoded = atob(trace.replace(/\n/g, ''));
+    readTraceShell.onData = raw =>
+        this.sendMessage(this.generateChunkReadResponse(raw));
 
+    readTraceShell.onClose = () => {
       this.sendMessage(
-          this.generateChunkReadResponse(decoded, /* last */ true));
+          this.generateChunkReadResponse(new Uint8Array(), /* last */ true));
       this.adb.disconnect();
       this.state = AdbState.READY;
     };
@@ -172,16 +162,16 @@
     console.assert(killOutput.length === 0);
   }
 
-  generateChunkReadResponse(data: string, last = false): ReadBuffersResponse {
+  generateChunkReadResponse(data: Uint8Array, last = false):
+      ReadBuffersResponse {
     return {
       type: 'ReadBuffersResponse',
-      slices: [{data: data as unknown as Uint8Array, lastSliceForPacket: last}]
+      slices: [{data, lastSliceForPacket: last}]
     };
   }
 
   generateReadTraceCommand(): string {
-    // TODO(nicomazz): Investigate why without base64 things break.
-    return `cat ${this.traceDestFile} | gzip | base64`;
+    return `gzip -c ${this.traceDestFile}`;
   }
 
   generateStartTracingCommand(tracingConfig: Uint8Array) {
diff --git a/ui/src/controller/adb_record_controller_jsdomtest.ts b/ui/src/controller/adb_record_controller_jsdomtest.ts
index 503f92d..4eded2f 100644
--- a/ui/src/controller/adb_record_controller_jsdomtest.ts
+++ b/ui/src/controller/adb_record_controller_jsdomtest.ts
@@ -14,6 +14,7 @@
 
 import {dingus} from 'dingusjs';
 
+import {stringToUint8Array} from '../base/string_utils';
 import {perfetto} from '../gen/protos';
 import {AdbStream, MockAdb, MockAdbStream} from './adb_interfaces';
 import {AdbConsumerPort} from './adb_record_controller';
@@ -93,7 +94,7 @@
   expect(sendMessage).toHaveBeenCalledTimes(0);
 
 
-  stream.onData('starting tracing Wrote 123 bytes', mockIntArray);
+  stream.onData(stringToUint8Array('starting tracing Wrote 123 bytes'));
   stream.onClose();
 
   expect(adbController.sendErrorMessage).toHaveBeenCalledTimes(0);
diff --git a/ui/src/controller/adb_socket_controller.ts b/ui/src/controller/adb_socket_controller.ts
new file mode 100644
index 0000000..2a03154
--- /dev/null
+++ b/ui/src/controller/adb_socket_controller.ts
@@ -0,0 +1,352 @@
+// 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.
+
+import * as protobuf from 'protobufjs/minimal';
+import {perfetto} from '../gen/protos';
+import {Adb, AdbStream} from './adb_interfaces';
+import {
+  isReadBuffersResponse,
+  ReadBuffersResponse
+} from './consumer_port_types';
+import {globals} from './globals';
+import {Consumer, RpcConsumerPort} from './record_controller_interfaces';
+
+enum State {
+  DISCONNECTED,
+  BINDING_IN_PROGRESS,
+  BOUND,
+}
+
+// See wire_protocol.proto for more details.
+const WIRE_PROTOCOL_HEADER_SIZE = 4;
+const MAX_IPC_BUFFER_SIZE = 128 * 1024;
+
+const PROTO_LEN_DELIMITED_WIRE_TYPE = 2;
+const TRACE_PACKET_PROTO_ID = 1;
+const TRACE_PACKET_PROTO_TAG =
+    (TRACE_PACKET_PROTO_ID << 3) | PROTO_LEN_DELIMITED_WIRE_TYPE;
+
+declare type Frame = perfetto.ipc.Frame;
+declare type IMethodInfo = perfetto.ipc.Frame.BindServiceReply.IMethodInfo;
+declare type ISlice = perfetto.protos.ReadBuffersResponse.ISlice;
+
+interface Command {
+  method: string;
+  params: Uint8Array;
+}
+
+export class AdbSocketConsumerPort extends RpcConsumerPort {
+  private state = State.DISCONNECTED;
+  private adb: Adb;
+  private socket?: AdbStream;
+  private device: USBDevice|undefined = undefined;
+  // Wire protocol request ID. After each request it is increased. It is needed
+  // to keep track of the type of request, and parse the response correctly.
+  private requestId = 1;
+
+  // Buffers received wire protocol data.
+  private incomingBuffer = new Uint8Array(MAX_IPC_BUFFER_SIZE);
+  private incomingBufferLen = 0;
+  private frameToParseLen = 0;
+
+  private availableMethods: IMethodInfo[] = [];
+  private serviceId = -1;
+
+  private resolveBindingPromise!: VoidFunction;
+  private requestMethods = new Map<number, string>();
+
+  // Needed for ReadBufferResponse: all the trace packets are split into
+  // several slices. |partialPacket| is the buffer for them. Once we receive a
+  // slice with the flag |lastSliceForPacket|, a new packet is created.
+  private partialPacket: ISlice[] = [];
+  // Accumulates trace packets into a proto trace file..
+  private traceProtoWriter = protobuf.Writer.create();
+
+  private commandQueue: Command[] = [];
+
+  constructor(adb: Adb, consumer: Consumer) {
+    super(consumer);
+    this.adb = adb;
+  }
+
+  async handleCommand(method: string, params: Uint8Array) {
+    this.commandQueue.push({method, params});
+
+    if (this.state === State.BINDING_IN_PROGRESS) return;
+    if (this.state === State.DISCONNECTED) {
+      this.state = State.BINDING_IN_PROGRESS;
+      this.device = await this.findDevice();
+      if (!this.device) {
+        this.sendErrorMessage(`Device with serial ${
+            globals.state.serialAndroidDeviceConnected} not found.`);
+        return;
+      }
+      await this.adb.connect(this.device);
+      await this.listenForMessages();
+      await this.bind();
+      this.traceProtoWriter = protobuf.Writer.create();
+      this.state = State.BOUND;
+    }
+
+    console.assert(this.state === State.BOUND);
+
+    for (const cmd of this.commandQueue) this.invoke(cmd.method, cmd.params);
+    this.commandQueue = [];
+  }
+
+  invoke(method: string, argsProto: Uint8Array) {
+    const requestId = this.requestId++;
+    const methodId = this.findMethodId(method);
+    if (methodId === undefined) {
+      this.sendErrorMessage('Calling unsupported method on target.');
+      console.error(`Method ${method} not supported by the target`);
+      return;
+    }
+    const frame = new perfetto.ipc.Frame({
+      requestId,
+      msgInvokeMethod: new perfetto.ipc.Frame.InvokeMethod(
+          {serviceId: this.serviceId, methodId, argsProto})
+    });
+    this.requestMethods.set(requestId, method);
+    this.sendFrame(frame);
+  }
+
+  async sendFrame(frame: Frame) {
+    console.assert(this.socket !== undefined);
+    if (!this.socket) return;
+    const frameProto: Uint8Array = perfetto.ipc.Frame.encode(frame).finish();
+    const frameLen = frameProto.length;
+    const buf = new Uint8Array(WIRE_PROTOCOL_HEADER_SIZE + frameLen);
+    const dv = new DataView(buf.buffer);
+    dv.setUint32(0, frameProto.length, /* littleEndian */ true);
+    for (let i = 0; i < frameLen; i++) {
+      dv.setUint8(WIRE_PROTOCOL_HEADER_SIZE + i, frameProto[i]);
+    }
+    await this.socket.write(buf);
+  }
+
+  async listenForMessages() {
+    this.socket = await this.adb.socket('/dev/socket/traced_consumer');
+
+    this.socket.onData = newData => this.handleReceivedData(newData);
+    this.socket.onClose = () => {
+      this.state = State.DISCONNECTED;
+      this.commandQueue = [];
+    };
+  }
+
+  private parseMessageSize(buffer: Uint8Array) {
+    const dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.length);
+    return dv.getUint32(0, true);
+  }
+
+  private parseMessage(frameBuffer: Uint8Array) {
+    const frame = perfetto.ipc.Frame.decode(frameBuffer);
+    this.handleIncomingFrame(frame);
+  }
+
+  private incompleteSizeHeader() {
+    if (!this.frameToParseLen) {
+      console.assert(this.incomingBufferLen < WIRE_PROTOCOL_HEADER_SIZE);
+      return true;
+    }
+    return false;
+  }
+
+  private canCompleteSizeHeader(newData: Uint8Array) {
+    return newData.length + this.incomingBufferLen > WIRE_PROTOCOL_HEADER_SIZE;
+  }
+
+  private canParseFullMessage(newData: Uint8Array) {
+    return this.frameToParseLen &&
+        this.incomingBufferLen + newData.length >= this.frameToParseLen;
+  }
+
+  private appendToIncomingBuffer(array: Uint8Array) {
+    this.incomingBuffer.set(array, this.incomingBufferLen);
+    this.incomingBufferLen += array.length;
+  }
+
+  handleReceivedData(newData: Uint8Array) {
+    if (this.incompleteSizeHeader() && this.canCompleteSizeHeader(newData)) {
+      const newDataBytesToRead =
+          WIRE_PROTOCOL_HEADER_SIZE - this.incomingBufferLen;
+      // Add to the incoming buffer the remaining bytes to arrive at
+      // WIRE_PROTOCOL_HEADER_SIZE
+      this.appendToIncomingBuffer(newData.subarray(0, newDataBytesToRead));
+      newData = newData.subarray(newDataBytesToRead);
+
+      this.frameToParseLen = this.parseMessageSize(this.incomingBuffer);
+      this.incomingBufferLen = 0;
+    }
+
+    // Parse all complete messages in incomingBuffer and newData.
+    while (this.canParseFullMessage(newData)) {
+      // All the message is in the newData buffer.
+      if (this.incomingBufferLen === 0) {
+        this.parseMessage(newData.subarray(0, this.frameToParseLen));
+        newData = newData.subarray(this.frameToParseLen);
+      } else {  // We need to complete the local buffer.
+        // Read the remaining part of this message.
+        const bytesToCompleteMessage =
+            this.frameToParseLen - this.incomingBufferLen;
+        this.appendToIncomingBuffer(
+            newData.subarray(0, bytesToCompleteMessage));
+        this.parseMessage(
+            this.incomingBuffer.subarray(0, this.frameToParseLen));
+        this.incomingBufferLen = 0;
+        // Remove the data just parsed.
+        newData = newData.subarray(bytesToCompleteMessage);
+      }
+      this.frameToParseLen = 0;
+      if (!this.canCompleteSizeHeader(newData)) break;
+
+      this.frameToParseLen =
+          this.parseMessageSize(newData.subarray(0, WIRE_PROTOCOL_HEADER_SIZE));
+      newData = newData.subarray(WIRE_PROTOCOL_HEADER_SIZE);
+    }
+    // Buffer the remaining data (part of the next header + message).
+    this.appendToIncomingBuffer(newData);
+  }
+
+  decodeResponse(
+      requestId: number, responseProto: Uint8Array, hasMore = false) {
+    const method = this.requestMethods.get(requestId);
+    if (!method) {
+      console.error(`Unknown request id: ${requestId}`);
+      this.sendErrorMessage(`Wire protocol error.`);
+      return;
+    }
+    const decoder = decoders.get(method);
+    if (decoder === undefined) {
+      console.error(`Unable to decode method: ${method}`);
+      return;
+    }
+    const decodedResponse = decoder(responseProto);
+    const response = {type: `${method}Response`, ...decodedResponse};
+
+    // TODO(nicomazz): Fix this.
+    // We assemble all the trace and then send it back to the main controller.
+    // This is a temporary solution, that will be changed in a following CL,
+    // because now both the chrome consumer port and the other adb consumer port
+    // send back the entire trace, while the correct behavior should be to send
+    // back the slices, that are assembled by the main record controller.
+    if (isReadBuffersResponse(response)) {
+      if (response.slices) this.handleSlices(response.slices);
+      if (!hasMore) this.sendReadBufferResponse();
+      return;
+    }
+    this.sendMessage(response);
+  }
+
+  handleSlices(slices: ISlice[]) {
+    for (const slice of slices) {
+      this.partialPacket.push(slice);
+      if (slice.lastSliceForPacket) {
+        const tracePacket = this.generateTracePacket(this.partialPacket);
+        this.traceProtoWriter.uint32(TRACE_PACKET_PROTO_TAG);
+        this.traceProtoWriter.bytes(tracePacket);
+        this.partialPacket = [];
+      }
+    }
+  }
+
+  generateTracePacket(slices: ISlice[]): Uint8Array {
+    let bufferSize = 0;
+    for (const slice of slices) bufferSize += slice.data!.length;
+    const fullBuffer = new Uint8Array(bufferSize);
+    let written = 0;
+    for (const slice of slices) {
+      const data = slice.data!;
+      fullBuffer.set(data, written);
+      written += data.length;
+    }
+    return fullBuffer;
+  }
+
+  sendReadBufferResponse() {
+    const readBufferResponse: ReadBuffersResponse = {
+      type: 'ReadBuffersResponse',
+      slices: [{data: this.traceProtoWriter.finish(), lastSliceForPacket: true}]
+    };
+
+    this.sendMessage(readBufferResponse);
+  }
+
+  bind() {
+    console.assert(this.socket !== undefined);
+    const requestId = this.requestId++;
+    const frame = new perfetto.ipc.Frame({
+      requestId,
+      msgBindService:
+          new perfetto.ipc.Frame.BindService({serviceName: 'ConsumerPort'})
+    });
+    return new Promise((resolve, _) => {
+      this.resolveBindingPromise = resolve;
+      this.sendFrame(frame);
+    });
+  }
+
+  findMethodId(method: string): number|undefined {
+    const methodObject = this.availableMethods.find((m) => m.name === method);
+    if (methodObject && methodObject.id) return methodObject.id;
+    return undefined;
+  }
+
+  async findDevice() {
+    if (!globals.state.androidDeviceConnected) return undefined;
+    const targetSerial = globals.state.androidDeviceConnected.serial;
+    const devices = await navigator.usb.getDevices();
+    return devices.find(d => d.serialNumber === targetSerial);
+  }
+
+  handleIncomingFrame(frame: perfetto.ipc.Frame) {
+    const requestId = frame.requestId as number;
+    switch (frame.msg) {
+      case 'msgBindServiceReply': {
+        const msgBindServiceReply = frame.msgBindServiceReply;
+        if (msgBindServiceReply && msgBindServiceReply.methods &&
+            msgBindServiceReply.serviceId) {
+          console.assert(msgBindServiceReply.success);
+          this.availableMethods = msgBindServiceReply.methods;
+          this.serviceId = msgBindServiceReply.serviceId;
+          this.resolveBindingPromise();
+          this.resolveBindingPromise = () => {};
+        }
+        return;
+      }
+      case 'msgInvokeMethodReply': {
+        const msgInvokeMethodReply = frame.msgInvokeMethodReply;
+        if (msgInvokeMethodReply && msgInvokeMethodReply.replyProto) {
+          console.assert(msgInvokeMethodReply.success);
+          this.decodeResponse(
+              requestId,
+              msgInvokeMethodReply.replyProto,
+              msgInvokeMethodReply.hasMore === true);
+        }
+        return;
+      }
+      default:
+        console.error(`not recognized frame message: ${frame.msg}`);
+    }
+  }
+}
+
+const decoders =
+    new Map<string, Function>()
+        .set('EnableTracing', perfetto.protos.EnableTracingResponse.decode)
+        .set('FreeBuffers', perfetto.protos.FreeBuffersResponse.decode)
+        .set('ReadBuffers', perfetto.protos.ReadBuffersResponse.decode)
+        .set('DisableTracing', perfetto.protos.DisableTracingResponse.decode)
+        .set('GetTraceStats', perfetto.protos.GetTraceStatsResponse.decode);
\ No newline at end of file
diff --git a/ui/src/controller/chrome_proxy_record_controller.ts b/ui/src/controller/chrome_proxy_record_controller.ts
index c2ce289..54a4f29 100644
--- a/ui/src/controller/chrome_proxy_record_controller.ts
+++ b/ui/src/controller/chrome_proxy_record_controller.ts
@@ -12,9 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import {uint8ArrayToString} from '../base/string_utils';
+import {stringToUint8Array, uint8ArrayToString} from '../base/string_utils';
 
-import {ConsumerPortResponse, Typed} from './consumer_port_types';
+import {
+  ConsumerPortResponse,
+  isConsumerPortResponse,
+  isReadBuffersResponse,
+  Typed
+} from './consumer_port_types';
 import {Consumer, RpcConsumerPort} from './record_controller_interfaces';
 
 export interface ChromeExtensionError extends Typed {
@@ -43,8 +48,8 @@
 export class ChromeExtensionConsumerPort extends RpcConsumerPort {
   private extensionPort: MessagePort;
 
-  constructor(extensionPort: MessagePort, consumerPortListener: Consumer) {
-    super(consumerPortListener);
+  constructor(extensionPort: MessagePort, consumer: Consumer) {
+    super(consumer);
     this.extensionPort = extensionPort;
     this.extensionPort.onmessage = this.onExtensionMessage.bind(this);
   }
@@ -52,11 +57,23 @@
   onExtensionMessage(message: {data: ChromeExtensionMessage}) {
     if (isError(message.data)) {
       this.sendErrorMessage(message.data.error);
-    } else if (isStatus(message.data)) {
-      this.sendStatus(message.data.status);
-    } else {
-      this.sendMessage(message.data);
+      return;
     }
+    if (isStatus(message.data)) {
+      this.sendStatus(message.data.status);
+      return;
+    }
+
+    console.assert(isConsumerPortResponse(message.data));
+    // In this else branch message.data will be a ConsumerPortResponse.
+    if (isReadBuffersResponse(message.data) && message.data.slices) {
+      // This is needed because we can't send an ArrayBuffer through a
+      // chrome.runtime.port. A string is sent instead, and here converted to
+      // an ArrayBuffer.
+      const slice = message.data.slices[0].data as unknown as string;
+      message.data.slices[0].data = stringToUint8Array(slice);
+    }
+    this.sendMessage(message.data);
   }
 
   handleCommand(method: string, requestData: Uint8Array): void {
diff --git a/ui/src/controller/consumer_port_types.ts b/ui/src/controller/consumer_port_types.ts
index bb3c4ea..8a249d4 100644
--- a/ui/src/controller/consumer_port_types.ts
+++ b/ui/src/controller/consumer_port_types.ts
@@ -28,6 +28,12 @@
 export type ConsumerPortResponse =
     EnableTracingResponse|ReadBuffersResponse|GetTraceStatsResponse;
 
+export function isConsumerPortResponse(obj: Typed):
+    obj is ConsumerPortResponse {
+  return isReadBuffersResponse(obj) || isEnableTracingResponse(obj) ||
+      isGetTraceStatsResponse(obj);
+}
+
 export function isReadBuffersResponse(obj: Typed): obj is ReadBuffersResponse {
   return obj.type === 'ReadBuffersResponse';
 }
diff --git a/ui/src/controller/record_controller.ts b/ui/src/controller/record_controller.ts
index 69a3f48..419c801 100644
--- a/ui/src/controller/record_controller.ts
+++ b/ui/src/controller/record_controller.ts
@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import {ungzip} from 'pako';
 import {Message, Method, rpc, RPCImplCallback} from 'protobufjs';
 
-import {stringToUint8Array, uint8ArrayToBase64} from '../base/string_utils';
+import {
+  uint8ArrayToBase64,
+} from '../base/string_utils';
 import {Actions} from '../common/actions';
 import {
   AndroidLogConfig,
@@ -42,6 +43,7 @@
 
 import {AdbOverWebUsb} from './adb';
 import {AdbConsumerPort} from './adb_record_controller';
+import {AdbSocketConsumerPort} from './adb_socket_controller';
 import {ChromeExtensionConsumerPort} from './chrome_proxy_record_controller';
 import {
   ConsumerPortResponse,
@@ -442,7 +444,7 @@
   private extensionPort: MessagePort;
   private recordingInProgress = false;
   private consumerPort: ConsumerPort;
-  private traceBuffer = '';
+  private traceBuffer: Uint8Array[] = [];
   private bufferUpdateInterval: ReturnType<typeof setTimeout>|undefined;
 
   // We have a different controller for each targetOS. The correct one will be
@@ -513,10 +515,10 @@
   onConsumerPortResponse(data: ConsumerPortResponse) {
     if (data === undefined) return;
     if (isReadBuffersResponse(data)) {
-      if (!data.slices) return;
+      if (!data.slices || data.slices.length === 0) return;
       // TODO(nicomazz): handle this as intended by consumer_port.proto.
-      this.traceBuffer += data.slices[0].data;
-      // TODO(nicomazz): Stream the chunks directly in the trace processor.
+      console.assert(data.slices.length === 1);
+      if (data.slices[0].data) this.traceBuffer.push(data.slices[0].data);
       if (data.slices[0].lastSliceForPacket) this.onTraceComplete();
     } else if (isEnableTracingResponse(data)) {
       this.readBuffers();
@@ -533,16 +535,24 @@
   onTraceComplete() {
     this.consumerPort.freeBuffers({});
     globals.dispatch(Actions.setRecordingStatus({status: undefined}));
-    if (globals.state.recordingCancelled) {
-      globals.dispatch(
-          Actions.setLastRecordingError({error: 'Recording cancelled.'}));
-      return;
-    }
-    const trace = ungzip(stringToUint8Array(this.traceBuffer));
+    const trace = this.generateTrace();
     globals.dispatch(Actions.openTraceFromBuffer({buffer: trace.buffer}));
-    this.traceBuffer = '';
+    this.traceBuffer = [];
   }
 
+  // TODO(nicomazz): stream each chunk into the trace processor, instead of
+  // creating a big long trace.
+  generateTrace() {
+    let traceLen = 0;
+    for (const chunk of this.traceBuffer) traceLen += chunk.length;
+    const completeTrace = new Uint8Array(traceLen);
+    let written = 0;
+    for (const chunk of this.traceBuffer) {
+      completeTrace.set(chunk, written);
+      written += chunk.length;
+    }
+    return completeTrace;
+  }
 
   getBufferUsagePercentage(data: GetTraceStatsResponse): number {
     if (!data.traceStats || !data.traceStats.bufferStats) return 0.0;
@@ -574,7 +584,7 @@
   // - Android device target: WebUSB is used to communicate using the adb
   // protocol. Actually, there is no full consumer_port implementation, but
   // only the support to start tracing and fetch the file.
-  getTargetController(target: TargetOs): RpcConsumerPort {
+  async getTargetController(target: TargetOs): Promise<RpcConsumerPort> {
     let controller = this.controllers.get(target);
     if (controller) return controller;
 
@@ -582,8 +592,12 @@
       controller = new ChromeExtensionConsumerPort(this.extensionPort, this);
     } else if (isAndroidTarget(target)) {
       // TODO(nicomazz): create the correct controller also based on the
-      // selected android device.
-      controller = new AdbConsumerPort(new AdbOverWebUsb(), this);
+      // selected android device. TargetOS may be changed from a single char to
+      // something else.
+      const socketAccess = await this.hasSocketAccess();
+      controller = socketAccess ?
+          new AdbSocketConsumerPort(new AdbOverWebUsb(), this) :
+          new AdbConsumerPort(new AdbOverWebUsb(), this);
     }
 
     if (!controller) throw Error(`Unknown target: ${target}`);
@@ -592,11 +606,16 @@
     return controller;
   }
 
-  private rpcImpl(
+  private hasSocketAccess() {
+    // TODO(nicomazz): implement proper logic
+    return Promise.resolve(false);
+  }
+
+  private async rpcImpl(
       method: RPCImplMethod, requestData: Uint8Array,
       _callback: RPCImplCallback) {
     try {
-      this.getTargetController(this.app.state.recordConfig.targetOS)
+      (await this.getTargetController(this.app.state.recordConfig.targetOS))
           .handleCommand(method.name, requestData);
     } catch (e) {
       console.error(`error invoking ${method}: ${e.message}`);
diff --git a/ui/src/controller/search_controller.ts b/ui/src/controller/search_controller.ts
index d9f9746..91b8d06 100644
--- a/ui/src/controller/search_controller.ts
+++ b/ui/src/controller/search_controller.ts
@@ -14,20 +14,22 @@
 
 import {Engine} from '../common/engine';
 import {CurrentSearchResults, SearchSummary} from '../common/search_data';
-import {TimeSpan, toNs} from '../common/time';
+import {TimeSpan} from '../common/time';
 
 import {Controller} from './controller';
-import {App, globals} from './globals';
+import {App} from './globals';
 
 export interface SearchControllerArgs {
   engine: Engine;
   app: App;
 }
 
+
 export class SearchController extends Controller<'main'> {
   private engine: Engine;
   private app: App;
   private previousSpan: TimeSpan;
+  private previousResolution: number;
   private previousSearch: string;
   private updateInProgress: boolean;
   private setupInProgress: boolean;
@@ -40,6 +42,7 @@
     this.previousSearch = '';
     this.updateInProgress = false;
     this.setupInProgress = true;
+    this.previousResolution = 1;
     this.setup().finally(() => {
       this.setupInProgress = false;
       this.run();
@@ -51,11 +54,6 @@
       using window;`);
     await this.query(`create virtual table search_summary_span
       using span_join(sched PARTITIONED cpu, search_summary_window);`);
-
-    await this.query(`create virtual table search_result_window
-      using window;`);
-    await this.query(`create virtual table search_result_span
-      using span_join(sched PARTITIONED cpu, search_result_window);`);
   }
 
   run() {
@@ -71,11 +69,16 @@
     }
     const newSpan = new TimeSpan(visibleState.startSec, visibleState.endSec);
     const newSearch = omniboxState.omnibox;
-    if (this.previousSpan.equals(newSpan) &&
+    const newResolution = visibleState.resolution;
+    if (this.previousSpan.contains(newSpan) &&
+        this.previousResolution === newResolution &&
         newSearch === this.previousSearch) {
       return;
     }
-    this.previousSpan = newSpan;
+    this.previousSpan = new TimeSpan(
+        Math.max(newSpan.start - newSpan.duration, 0),
+        newSpan.end + newSpan.duration);
+    this.previousResolution = newResolution;
     this.previousSearch = newSearch;
     if (newSearch === '' || newSearch.length < 4) {
       this.app.publish('Search', {
@@ -95,10 +98,9 @@
 
     const startNs = Math.round(newSpan.start * 1e9);
     const endNs = Math.round(newSpan.end * 1e9);
-    const resolution = visibleState.resolution;
     this.updateInProgress = true;
     const computeSummary =
-        this.update(newSearch, startNs, endNs, resolution).then(summary => {
+        this.update(newSearch, startNs, endNs, newResolution).then(summary => {
           this.app.publish('Search', summary);
         });
 
@@ -171,17 +173,9 @@
 
     const utids = [...rawUtidResult.columns[0].longValues!];
 
-    await this.query(`update search_result_window set
-    window_start=${toNs(globals.state.traceTime.startSec)},
-    window_dur=${
-        toNs(
-            globals.state.traceTime.endSec - globals.state.traceTime.startSec)},
-    quantum=0
-    where rowid = 0;`);
-
     const rawResult = await this.query(`
     select row_id, ts, utid, cpu
-    from search_result_span
+    from sched
     where utid in (${utids.join(',')}) order by ts`);
 
     const numRows = +rawResult.numRecords;
diff --git a/ui/src/frontend/index.ts b/ui/src/frontend/index.ts
index bf59470..4a3081b 100644
--- a/ui/src/frontend/index.ts
+++ b/ui/src/frontend/index.ts
@@ -248,6 +248,8 @@
   }
 
   updateAvailableAdbDevices();
+  navigator.usb.addEventListener('connect', updateAvailableAdbDevices);
+  navigator.usb.addEventListener('disconnect', updateAvailableAdbDevices);
 
   // This forwards the messages from the controller to the extension
   extensionLocalChannel.port2.onmessage = ({data}) => {
diff --git a/ui/src/frontend/record_page.ts b/ui/src/frontend/record_page.ts
index ac9758a..7709d67 100644
--- a/ui/src/frontend/record_page.ts
+++ b/ui/src/frontend/record_page.ts
@@ -610,7 +610,7 @@
 
   const selectedIndex = selected ? baseTargets.length +
           availableAndroidDevices.findIndex(d => d.serial === selected.serial) :
-                                   undefined;
+                                   0;
 
   return m(
       '.target',
@@ -638,6 +638,7 @@
     draft.targetOS = adbDevice ? adbDevice.os as TargetOs : target as TargetOs;
   });
   globals.dispatch(Actions.setRecordConfig({config: traceCfg}));
+  globals.rafScheduler.scheduleFullRedraw();
 }
 
 function Instructions(cssClass: string) {
@@ -794,8 +795,10 @@
 
   const targetOs = state.recordConfig.targetOS;
   if (isAndroidTarget(targetOs)) {
-    buttons.push(showCmd);
-    if (realDeviceTarget) buttons.push(start);
+    if (!recInProgress) {
+      buttons.push(showCmd);
+      if (realDeviceTarget) buttons.push(start);
+    }
   } else if (isChromeTarget(targetOs) && state.extensionInstalled) {
     buttons.push(start);
   } else if (isLinuxTarget(targetOs)) {
@@ -882,9 +885,31 @@
   });
 
   globals.dispatch(Actions.setAvailableDevices({devices: availableAdbDevices}));
+  selectAndroidDeviceIfAvailable(availableAdbDevices);
+  globals.rafScheduler.scheduleFullRedraw();
   return availableAdbDevices;
 }
 
+function selectAndroidDeviceIfAvailable(
+    availableAdbDevices: AdbRecordingTarget[]) {
+  // If there is an android device attached, but not selected, select it by
+  // default.
+  if (!globals.state.androidDeviceConnected && availableAdbDevices.length) {
+    globals.dispatch(
+        Actions.setAndroidDevice({target: availableAdbDevices[0]}));
+    return;
+  }
+
+  // If a device was selected, but it's not available anymore, reset the
+  // androidConnectedDevice to null.
+  const deviceConnected = globals.state.androidDeviceConnected;
+  if (deviceConnected &&
+      availableAdbDevices.find(e => e.serial === deviceConnected.serial) ===
+          undefined) {
+    globals.dispatch(Actions.setAndroidDevice({target: undefined}));
+  }
+}
+
 function recordMenu(routePage: string) {
   const targetOS = globals.state.recordConfig.targetOS;
   const chromeProbe =
@@ -893,10 +918,11 @@
           m('i.material-icons', 'laptop_chromebook'),
           m('.title', 'Chrome'),
           m('.sub', 'Chrome traces')));
+  const recInProgress = globals.state.recordingInProgress;
 
   return m(
       '.record-menu',
-      {onclick: () => globals.rafScheduler.scheduleFullRedraw()},
+      {class: recInProgress ? 'disabled' : ''},
       m('header', 'Trace config'),
       m('ul',
         m('a[href="#!/record?p=buffers"]',
@@ -972,6 +998,7 @@
 
     return m(
         '.record-page',
+        globals.state.recordingInProgress ? m('.hider') : [],
         m('.record-container', RecordHeader(), recordMenu(routePage), pages));
   }
 });
diff --git a/ui/src/frontend/topbar.ts b/ui/src/frontend/topbar.ts
index 4740978..16228b5 100644
--- a/ui/src/frontend/topbar.ts
+++ b/ui/src/frontend/topbar.ts
@@ -191,14 +191,15 @@
                   m('i.material-icons.right', 'keyboard_arrow_right')),
                 ) :
             '',
-        commandMode ?
-            '' :
-            m('.help',
-              {
-                title:
-                    'Search functionality is in beta. Improvements coming soon!'
-              },
-              m('i.material-icons', 'help')),
+        commandMode ? '' :
+                      m('.help',
+                        {
+                          title: 'Search is in beta. Improvements coming soon!',
+                          onclick: () => {
+                            window.open('http://b/111169965', '_blank');
+                          }
+                        },
+                        m('i.material-icons', 'help')),
         m('.omnibox-results', results));
   }
 }
diff --git a/ui/src/frontend/track.ts b/ui/src/frontend/track.ts
index cd0e6da..d8ae5a0 100644
--- a/ui/src/frontend/track.ts
+++ b/ui/src/frontend/track.ts
@@ -23,7 +23,7 @@
 /**
  * This interface forces track implementations to have some static properties.
  * Typescript does not have abstract static members, which is why this needs to
- * be in a seperate interface.
+ * be in a separate interface.
  */
 export interface TrackCreator {
   // Store the kind explicitly as a string as opposed to using class.kind in
diff --git a/ui/src/tracks/process_scheduling/controller.ts b/ui/src/tracks/process_scheduling/controller.ts
index 65f02d7..1dfc8cb 100644
--- a/ui/src/tracks/process_scheduling/controller.ts
+++ b/ui/src/tracks/process_scheduling/controller.ts
@@ -89,7 +89,7 @@
     const endNs = toNs(end);
     const numBuckets = Math.ceil((endNs - startNs) / bucketSizeNs);
 
-    // cpu < maxCpu improves perfomance a lot since the window table can
+    // cpu < maxCpu improves performance a lot since the window table can
     // avoid generating many rows.
     const query = `select
         quantum_ts as bucket,
@@ -123,7 +123,7 @@
 
   private async computeSlices(start: number, end: number, resolution: number):
       Promise<SliceData> {
-    // cpu < maxCpu improves perfomance a lot since the window table can
+    // cpu < maxCpu improves performance a lot since the window table can
     // avoid generating many rows.
     const query = `select ts,dur,cpu,utid from ${this.tableName('span')}
         join