perfetto: rework proto descriptor gen to inform gn about deps

The state before today:
1) All the non descriptor rules (lite, zero, gen, ipc) all need
   to know about all the recursive proto deps to ensure rebuilds
   when files are changeds (even though techincally the protoc
   compiler does not actually look at this info)
2) For descriptor rules, we actually rely on protoc to do all
   the lookups on its side.
3) For Bazel/Android.bp, we hacked soemthing custom to propogate
   the depenendencies instead of using gn properly (at the time
   I did not understand gn enough to write the correct templates)

The problem:
If we are using RBE, we need GN to know about deps so that scheduling
of compile actions can correctly figure out which sources are necessary
to build which others. We cannot just rely on protoc for this

The solution:
Unhack a bunch of custom stufff around how we handle descriptors to
teach GN properly about the deps. This involes the following:
1) Make source_sets groups instead of actions which allows proper
   propogation of deps (which was something badly missing with action)
2) Remove source_set and descriptor from being proto_generators:
   proto_generators now strictly corresponds to C++ codegen.
3) Always generate a source_set target (behind the scenes) to allow
   depending on it from any other proto target (this is very similar
   to how Bazel/Blaze work)
4) Make descriptors just rely on generate_descriptor option and
   specify the top level proto with descriptor_root_source (which is
   what will be passed to protoc in the end)

This should have a minimal diff for bazel/gn which fixing the RBE
problem. It also reduces the complexity of a bunch of random proto
build rules throughout the codebase.

Really as hard as it is to believe, this is noop change...

Change-Id: Ieab7ea58efe75ad919d45763965529b3cda02751
diff --git a/Android.bp b/Android.bp
index bd33cb0..a7de450 100644
--- a/Android.bp
+++ b/Android.bp
@@ -11697,27 +11697,6 @@
     ],
 }
 
-// GN: //src/protozero:test_messages_descriptor
-genrule {
-    name: "perfetto_src_protozero_test_messages_descriptor",
-    srcs: [
-        "src/protozero/test/example_proto/extensions.proto",
-        "src/protozero/test/example_proto/library.proto",
-        "src/protozero/test/example_proto/library_internals/galaxies.proto",
-        "src/protozero/test/example_proto/other_package/test_messages.proto",
-        "src/protozero/test/example_proto/subpackage/test_messages.proto",
-        "src/protozero/test/example_proto/test_messages.proto",
-        "src/protozero/test/example_proto/upper_import.proto",
-    ],
-    tools: [
-        "aprotoc",
-    ],
-    cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --descriptor_set_out=$(out) $(in)",
-    out: [
-        "perfetto_src_protozero_test_messages_descriptor.bin",
-    ],
-}
-
 // GN: //src/protozero:testing_messages_cpp
 filegroup {
     name: "perfetto_src_protozero_testing_messages_cpp",
@@ -11778,6 +11757,27 @@
     ],
 }
 
+// GN: //src/protozero:testing_messages_descriptor
+genrule {
+    name: "perfetto_src_protozero_testing_messages_descriptor",
+    srcs: [
+        "src/protozero/test/example_proto/extensions.proto",
+        "src/protozero/test/example_proto/library.proto",
+        "src/protozero/test/example_proto/library_internals/galaxies.proto",
+        "src/protozero/test/example_proto/other_package/test_messages.proto",
+        "src/protozero/test/example_proto/subpackage/test_messages.proto",
+        "src/protozero/test/example_proto/test_messages.proto",
+        "src/protozero/test/example_proto/upper_import.proto",
+    ],
+    tools: [
+        "aprotoc",
+    ],
+    cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --descriptor_set_out=$(out) $(in)",
+    out: [
+        "perfetto_src_protozero_testing_messages_descriptor.bin",
+    ],
+}
+
 // GN: //src/protozero:testing_messages_lite
 filegroup {
     name: "perfetto_src_protozero_testing_messages_lite",
@@ -12359,7 +12359,7 @@
 genrule {
     name: "perfetto_src_trace_processor_gen_cc_test_messages_descriptor",
     srcs: [
-        ":perfetto_src_protozero_test_messages_descriptor",
+        ":perfetto_src_protozero_testing_messages_descriptor",
     ],
     cmd: "$(location tools/gen_cc_proto_descriptor.py) --gen_dir=$(genDir) --cpp_out=$(out) $(in)",
     out: [
diff --git a/BUILD b/BUILD
index 30c3226..9335ace 100644
--- a/BUILD
+++ b/BUILD
@@ -5154,7 +5154,7 @@
     deps = [
         ":protos_perfetto_metrics_android_protos",
         ":protos_perfetto_metrics_protos",
-    ],
+    ] + PERFETTO_CONFIG.deps.protobuf_descriptor_proto,
 )
 
 # GN target: //protos/perfetto/trace/android:android_track_event_descriptor
@@ -5162,7 +5162,6 @@
     name = "protos_perfetto_trace_android_android_track_event_descriptor",
     deps = [
         ":protos_perfetto_trace_android_android_track_event_protos",
-        ":protos_perfetto_trace_track_event_protos",
     ],
     outs = [
         "protos_perfetto_trace_android_android_track_event_descriptor.bin",
@@ -5181,9 +5180,6 @@
     deps = [
         ":protos_perfetto_trace_track_event_protos",
     ],
-    exports = [
-        ":protos_perfetto_trace_track_event_protos",
-    ],
 )
 
 # GN target: //protos/perfetto/trace/android:source_set
@@ -5237,8 +5233,7 @@
 perfetto_proto_descriptor(
     name = "protos_perfetto_trace_android_winscope_descriptor",
     deps = [
-        ":protos_perfetto_trace_android_winscope_extensions_protos",
-        ":protos_perfetto_trace_android_winscope_regular_protos",
+        ":protos_perfetto_trace_android_winscope_protos",
     ],
     outs = [
         "protos_perfetto_trace_android_winscope_descriptor.bin",
@@ -5310,6 +5305,23 @@
     ],
 )
 
+# GN target: //protos/perfetto/trace/android:winscope_source_set
+perfetto_proto_library(
+    name = "protos_perfetto_trace_android_winscope_protos",
+    srcs = [
+        "protos/perfetto/trace/android/winscope.proto",
+    ],
+    visibility = [
+        PERFETTO_CONFIG.proto_library_visibility,
+    ],
+    deps = [
+        ":protos_perfetto_common_protos",
+        ":protos_perfetto_trace_android_winscope_common_protos",
+        ":protos_perfetto_trace_android_winscope_extensions_protos",
+        ":protos_perfetto_trace_android_winscope_regular_protos",
+    ] + PERFETTO_CONFIG.deps.protobuf_descriptor_proto,
+)
+
 # GN target: //protos/perfetto/trace/android:winscope_regular_source_set
 perfetto_proto_library(
     name = "protos_perfetto_trace_android_winscope_regular_protos",
@@ -5377,7 +5389,7 @@
 perfetto_proto_descriptor(
     name = "protos_perfetto_trace_descriptor",
     deps = [
-        ":protos_perfetto_trace_non_minimal_protos",
+        ":protos_perfetto_trace_protos",
     ],
     outs = [
         "protos_perfetto_trace_descriptor.bin",
@@ -5850,6 +5862,50 @@
     ],
 )
 
+# GN target: //protos/perfetto/trace:source_set
+perfetto_proto_library(
+    name = "protos_perfetto_trace_protos",
+    visibility = [
+        PERFETTO_CONFIG.proto_library_visibility,
+    ],
+    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_interceptors_protos",
+        ":protos_perfetto_config_power_protos",
+        ":protos_perfetto_config_process_stats_protos",
+        ":protos_perfetto_config_profiling_protos",
+        ":protos_perfetto_config_protos",
+        ":protos_perfetto_config_statsd_protos",
+        ":protos_perfetto_config_sys_stats_protos",
+        ":protos_perfetto_config_system_info_protos",
+        ":protos_perfetto_config_track_event_protos",
+        ":protos_perfetto_trace_android_protos",
+        ":protos_perfetto_trace_android_winscope_common_protos",
+        ":protos_perfetto_trace_android_winscope_regular_protos",
+        ":protos_perfetto_trace_chrome_protos",
+        ":protos_perfetto_trace_etw_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_non_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_statsd_protos",
+        ":protos_perfetto_trace_sys_stats_protos",
+        ":protos_perfetto_trace_system_info_protos",
+        ":protos_perfetto_trace_track_event_protos",
+        ":protos_perfetto_trace_translation_protos",
+    ],
+)
+
 # GN target: //protos/perfetto/trace/ps:source_set
 perfetto_proto_library(
     name = "protos_perfetto_trace_ps_protos",
diff --git a/gn/proto_library.gni b/gn/proto_library.gni
index 2865fe2..6b9fb7c 100644
--- a/gn/proto_library.gni
+++ b/gn/proto_library.gni
@@ -79,13 +79,12 @@
       component_build_force_source_set = true
     }
 
-    if (defined(invoker.deps)) {
-      deps = invoker.deps
-    } else {
-      deps = []
-    }
-
+    # Convert deps to link_deps: the proto_library rule requires that C++ files
+    # are passed in as link_deps wheras in Perfetto, we always works with deps.
     link_deps = []
+    if (defined(invoker.deps)) {
+      link_deps += invoker.deps
+    }
 
     # omit_protozero_dep is intended to be used when protozero_library
     # is used in Chrome (for generation of code for proto extensions)
@@ -143,16 +142,12 @@
       "$perfetto_root_path/include/perfetto/base",
       "$perfetto_root_path/src/protozero",
     ]
-    if (defined(invoker.link_deps)) {
-      link_deps += invoker.link_deps
-    }
 
-    deps = []
-
+    # Convert deps to link_deps: the proto_library rule requires that C++ files
+    # are passed in as link_deps wheras in Perfetto, we always works with deps.
     if (defined(invoker.deps)) {
-      deps += invoker.deps
+      link_deps += invoker.deps
     }
-
     forward_variables_from(invoker,
                            [
                              "defines",
@@ -179,7 +174,6 @@
     generator_plugin_label =
         "$perfetto_root_path/src/ipc/protoc_plugin:ipc_plugin"
     generator_plugin_suffix = ".ipc"
-    deps = []
     link_deps = [ "$perfetto_root_path/gn:default_deps" ]
     if (perfetto_component_type == "static_library") {
       link_deps += [ "$perfetto_root_path/src/ipc:perfetto_ipc" ]
@@ -201,15 +195,16 @@
       }
     }
 
+    # Convert deps to link_deps: the proto_library rule requires that C++ files
+    # are passed in as link_deps wheras in Perfetto, we always works with deps.
     if (defined(invoker.deps)) {
-      deps += invoker.deps
+      link_deps += invoker.deps
     }
     forward_variables_from(invoker,
                            [
                              "defines",
                              "extra_configs",
                              "include_dirs",
-                             "link_deps",
                              "proto_in_dir",
                              "proto_out_dir",
                              "generator_plugin_options",
@@ -238,10 +233,14 @@
       generator_plugin_label =
           "$perfetto_root_path/buildtools/grpc:grpc_cpp_plugin"
       generator_plugin_suffix = ".grpc.pb"
-      deps = [ "$perfetto_root_path/buildtools/grpc:grpc++" ]
+      link_deps = [ "$perfetto_root_path/buildtools/grpc:grpc++" ]
       public_configs = [ "$perfetto_root_path/buildtools:grpc_gen_config" ]
+
+      # Convert deps to link_deps: the proto_library rule requires that C++
+      # files are passed in as link_deps wheras in Perfetto, we always works
+      # with deps.
       if (defined(invoker.deps)) {
-        deps += invoker.deps
+        link_deps += invoker.deps
       }
       forward_variables_from(invoker,
                              [
@@ -265,7 +264,6 @@
       "zero",
       "lite",
       "cpp",
-      "source_set",
     ]
   }
 
@@ -282,47 +280,104 @@
     import_dirs_ = []
   }
 
-  vars_to_forward = [
-    "sources",
-    "visibility",
-    "testonly",
-    "exclude_imports",
-    "link_deps",
-  ]
   expansion_token = "@TYPE@"
 
-  # gn:public_config propagates the gen dir as include directory. We
-  # disable the proto_library's public_config to avoid duplicate include
-  # directory command line flags (crbug.com/1043279, crbug.com/gn/142).
-  propagate_imports_configs_ = false
+  # The source set target should always be generated as it is used by the
+  # build generators and for generating descriptors.
+  source_set_target_name =
+      string_replace(target_name, expansion_token, "source_set")
+  group(source_set_target_name) {
+    public_deps_ = []
+    if (defined(invoker.public_deps)) {
+      foreach(dep, invoker.public_deps) {
+        # Get the absolute target path
+        mapped_dep = string_replace(dep, expansion_token, "source_set")
+        public_deps_ += [ mapped_dep ]
+      }
+    }
+
+    deps = []
+    if (defined(invoker.deps)) {
+      foreach(dep, invoker.deps) {
+        mapped_dep = string_replace(dep, expansion_token, "source_set")
+        deps += [ mapped_dep ]
+      }
+    }
+    deps += public_deps_
+
+    sources = []
+    foreach(source, invoker.sources) {
+      sources += [ get_path_info(source, "abspath") ]
+    }
+
+    metadata = {
+      proto_library_sources = sources
+      proto_import_dirs = import_dirs_
+      exports = []
+      foreach(dep, public_deps_) {
+        exports +=
+            [ get_label_info(dep, "dir") + ":" + get_label_info(dep, "name") ]
+      }
+    }
+  }
+
+  # Generate the descriptor if the option is set.
+  if (defined(invoker.generate_descriptor)) {
+    target_name_ = string_replace(target_name, expansion_token, "descriptor")
+    proto_library(target_name_) {
+      proto_in_dir = proto_path
+      proto_out_dir = proto_path
+      generate_python = false
+      generate_cc = false
+      generate_descriptor = rebase_path(invoker.generate_descriptor, proto_path)
+      sources = [ invoker.descriptor_root_source ]
+      import_dirs = import_dirs_
+      deps = [ ":${source_set_target_name}" ]
+      forward_variables_from(invoker,
+                             [
+                               "visibility",
+                               "testonly",
+                               "exclude_imports",
+                             ])
+    }
+  }
 
   foreach(gen_type, proto_generators) {
     target_name_ = string_replace(target_name, expansion_token, gen_type)
 
     # Translate deps from xxx:@TYPE@ to xxx:lite/zero.
-    deps_ = []
+    all_deps_ = []
     if (defined(invoker.deps)) {
       foreach(dep, invoker.deps) {
-        deps_ += [ string_replace(dep, expansion_token, gen_type) ]
+        all_deps_ += [ string_replace(dep, expansion_token, gen_type) ]
       }
     }
 
     # The distinction between deps and public_deps does not matter for GN
     # but Bazel cares about the difference so we distinguish between the two.
-    public_deps_ = []
     if (defined(invoker.public_deps)) {
       foreach(dep, invoker.public_deps) {
-        public_deps_ = [ string_replace(dep, expansion_token, gen_type) ]
+        all_deps_ += [ string_replace(dep, expansion_token, gen_type) ]
       }
     }
-    deps_ += public_deps_
+
+    # gn:public_config propagates the gen dir as include directory. We
+    # disable the proto_library's public_config to avoid duplicate include
+    # directory command line flags (crbug.com/1043279, crbug.com/gn/142).
+    propagate_imports_configs_ = false
+    vars_to_forward = []
+    vars_to_forward += [
+      "sources",
+      "visibility",
+      "testonly",
+    ]
 
     if (gen_type == "zero") {
       protozero_library(target_name_) {
         proto_in_dir = proto_path
         proto_out_dir = proto_path
         generator_plugin_options = "wrapper_namespace=pbzero"
-        deps = deps_
+        deps = all_deps_
         propagate_imports_configs = propagate_imports_configs_
         import_dirs = import_dirs_
         forward_variables_from(invoker, vars_to_forward)
@@ -332,7 +387,7 @@
         proto_in_dir = proto_path
         proto_out_dir = proto_path
         generator_plugin_options = "wrapper_namespace=gen"
-        deps = deps_
+        deps = all_deps_
         propagate_imports_configs = propagate_imports_configs_
         import_dirs = import_dirs_
         forward_variables_from(invoker, vars_to_forward)
@@ -343,7 +398,7 @@
         proto_in_dir = proto_path
         proto_out_dir = proto_path
         generator_plugin_options = "wrapper_namespace=gen"
-        deps = deps_ + [ ":$cpp_target_name_" ]
+        deps = all_deps_ + [ ":$cpp_target_name_" ]
         propagate_imports_configs = propagate_imports_configs_
         import_dirs = import_dirs_
         forward_variables_from(invoker, vars_to_forward)
@@ -353,59 +408,12 @@
         proto_in_dir = proto_path
         proto_out_dir = proto_path
         generate_python = false
-        deps = deps_
+        link_deps = all_deps_
         cc_generator_options = "lite=true:"
         propagate_imports_configs = propagate_imports_configs_
         import_dirs = import_dirs_
         forward_variables_from(invoker, vars_to_forward)
       }
-    } else if (gen_type == "descriptor") {
-      proto_library(target_name_) {
-        proto_in_dir = proto_path
-        proto_out_dir = proto_path
-        generate_python = false
-        generate_cc = false
-        generate_descriptor =
-            rebase_path(invoker.generate_descriptor, proto_path)
-        deps = deps_
-        import_dirs = import_dirs_
-        forward_variables_from(invoker, vars_to_forward + [ "proto_deps" ])
-      }
-
-      # Not needed for descriptor proto_library target.
-      not_needed([ "propagate_imports_configs_" ])
-    } else if (gen_type == "source_set") {
-      action(target_name_) {
-        out_path = "$target_gen_dir/" + target_name_
-        rebased_out_path =
-            rebase_path(target_gen_dir, root_build_dir) + "/" + target_name_
-
-        script = "$perfetto_root_path/tools/touch_file.py"
-        args = [
-          "--output",
-          rebased_out_path,
-        ]
-        outputs = [ out_path ]
-        deps = deps_
-
-        metadata = {
-          proto_library_sources = invoker.sources
-          proto_import_dirs = import_dirs_
-          exports = []
-          foreach(i, public_deps_) {
-            # Get the absolute target path
-            exports +=
-                [ get_label_info(i, "dir") + ":" + get_label_info(i, "name") ]
-          }
-        }
-        forward_variables_from(invoker, vars_to_forward)
-      }
-
-      # Not needed for source_set proto_library target.
-      not_needed([
-                   "propagate_imports_configs_",
-                   "proto_path",
-                 ])
     } else {
       assert(false, "Invalid 'proto_generators' value.")
     }
diff --git a/gn/standalone/proto_library.gni b/gn/standalone/proto_library.gni
index 0fb119a..93ed9c9 100644
--- a/gn/standalone/proto_library.gni
+++ b/gn/standalone/proto_library.gni
@@ -222,13 +222,6 @@
       deps = []
     }
 
-    # TODO(hjd): Avoid adding to deps here this.
-    # When we generate BUILD files we need find the transitive proto,
-    # dependencies, so also add link_deps to actual deps so they show up
-    # in gn desc.
-    if (defined(invoker.link_deps)) {
-      deps += invoker.link_deps
-    }
     if (generate_with_plugin) {
       inputs += [ plugin_path ]
       if (defined(plugin_host_label)) {
@@ -237,9 +230,12 @@
       }
     }
 
-    if (defined(invoker.deps)) {
+    if (generate_descriptor != "") {
       deps += invoker.deps
     }
+    if (defined(invoker.link_deps)) {
+      deps += invoker.link_deps
+    }
   }  # action(action_name)
 
   # The source_set that builds the generated .pb.cc files.
@@ -304,5 +300,4 @@
       }
     }  # source_set(source_set_name)
   }
-  not_needed(invoker, ["proto_deps"])
 }  # template
diff --git a/protos/perfetto/bigtrace/BUILD.gn b/protos/perfetto/bigtrace/BUILD.gn
index 1ba673b..c1b9fba 100644
--- a/protos/perfetto/bigtrace/BUILD.gn
+++ b/protos/perfetto/bigtrace/BUILD.gn
@@ -18,7 +18,6 @@
   proto_generators = [
     "lite",
     "zero",
-    "source_set",
   ]
   deps = [ "../trace_processor:@TYPE@" ]
   sources = [ "worker.proto" ]
@@ -28,7 +27,6 @@
   proto_generators = [
     "lite",
     "zero",
-    "source_set",
   ]
   deps = [ "../trace_processor:@TYPE@" ]
   sources = [ "orchestrator.proto" ]
diff --git a/protos/perfetto/common/BUILD.gn b/protos/perfetto/common/BUILD.gn
index 1a250b2..e92b631 100644
--- a/protos/perfetto/common/BUILD.gn
+++ b/protos/perfetto/common/BUILD.gn
@@ -41,6 +41,5 @@
     "lite",
     "zero",
     "cpp",
-    "source_set",
   ]
 }
diff --git a/protos/perfetto/config/BUILD.gn b/protos/perfetto/config/BUILD.gn
index eb8c3da..d58f59b 100644
--- a/protos/perfetto/config/BUILD.gn
+++ b/protos/perfetto/config/BUILD.gn
@@ -46,11 +46,7 @@
     "test_config.proto",
     "trace_config.proto",
   ]
-}
 
-perfetto_proto_library("descriptor") {
-  proto_generators = [ "descriptor" ]
   generate_descriptor = "config.descriptor"
-  link_deps = [ ":source_set" ]
-  sources = [ "trace_config.proto" ]
+  descriptor_root_source = "trace_config.proto"
 }
diff --git a/protos/perfetto/config/chrome/BUILD.gn b/protos/perfetto/config/chrome/BUILD.gn
index 4397cfc..3a144ee 100644
--- a/protos/perfetto/config/chrome/BUILD.gn
+++ b/protos/perfetto/config/chrome/BUILD.gn
@@ -16,7 +16,9 @@
 import("../../../../gn/proto_library.gni")
 
 perfetto_proto_library("scenario_descriptor") {
-  proto_generators = [ "descriptor" ]
-  generate_descriptor = "scenario_config.descriptor"
+  proto_generators = []
+  deps = [ "../config:@TYPE@" ]
   sources = [ "scenario_config.proto" ]
+  generate_descriptor = "scenario_config.descriptor"
+  descriptor_root_source = "scenario_config.proto"
 }
diff --git a/protos/perfetto/ipc/BUILD.gn b/protos/perfetto/ipc/BUILD.gn
index 6d7eccb..a2d3fac 100644
--- a/protos/perfetto/ipc/BUILD.gn
+++ b/protos/perfetto/ipc/BUILD.gn
@@ -21,7 +21,6 @@
   proto_generators = [
     "ipc",
     "cpp",
-    "source_set",
   ]
   sources = [
     "consumer_port.proto",
@@ -41,7 +40,6 @@
   proto_generators = [
     "zero",
     "cpp",
-    "source_set",
   ]
   sources = [ "wire_protocol.proto" ]
 }
diff --git a/protos/perfetto/metrics/BUILD.gn b/protos/perfetto/metrics/BUILD.gn
index c8accd7..d90ef8c 100644
--- a/protos/perfetto/metrics/BUILD.gn
+++ b/protos/perfetto/metrics/BUILD.gn
@@ -16,26 +16,15 @@
 import("../../../gn/proto_library.gni")
 
 perfetto_proto_library("@TYPE@") {
-  proto_generators = [
-    "lite",
-    "source_set",
-  ]
+  proto_generators = [ "lite" ]
   deps = [ "android:@TYPE@" ]
   sources = [ "metrics.proto" ]
+  generate_descriptor = "metrics.descriptor"
+  descriptor_root_source = "metrics.proto"
 }
 
 perfetto_proto_library("custom_options_@TYPE@") {
-  proto_generators = [
-    "lite",
-    "source_set",
-  ]
+  proto_generators = [ "lite" ]
   sources = [ "custom_options.proto" ]
   import_dirs = [ "${perfetto_protobuf_src_dir}" ]
 }
-
-perfetto_proto_library("descriptor") {
-  proto_generators = [ "descriptor" ]
-  generate_descriptor = "metrics.descriptor"
-  link_deps = [ ":source_set" ]
-  sources = [ "metrics.proto" ]
-}
diff --git a/protos/perfetto/metrics/android/BUILD.gn b/protos/perfetto/metrics/android/BUILD.gn
index 35a3203..ba0f60f 100644
--- a/protos/perfetto/metrics/android/BUILD.gn
+++ b/protos/perfetto/metrics/android/BUILD.gn
@@ -15,10 +15,7 @@
 import("../../../../gn/proto_library.gni")
 
 perfetto_proto_library("@TYPE@") {
-  proto_generators = [
-    "lite",
-    "source_set",
-  ]
+  proto_generators = [ "lite" ]
   sources = [
     "ad_services_metric.proto",
     "android_anomaly_metric.proto",
diff --git a/protos/perfetto/metrics/chrome/BUILD.gn b/protos/perfetto/metrics/chrome/BUILD.gn
index 88018af..bf47885 100644
--- a/protos/perfetto/metrics/chrome/BUILD.gn
+++ b/protos/perfetto/metrics/chrome/BUILD.gn
@@ -15,10 +15,7 @@
 import("../../../../gn/proto_library.gni")
 
 perfetto_proto_library("@TYPE@") {
-  proto_generators = [
-    "lite",
-    "source_set",
-  ]
+  proto_generators = [ "lite" ]
   import_dirs = [ "${perfetto_protobuf_src_dir}" ]
   deps = [
     "..:@TYPE@",
@@ -42,12 +39,6 @@
     "unsymbolized_args.proto",
     "user_event_hashes.proto",
   ]
-}
-
-perfetto_proto_library("descriptor") {
-  proto_generators = [ "descriptor" ]
-  import_dirs = [ "${perfetto_protobuf_src_dir}" ]
   generate_descriptor = "all_chrome_metrics.descriptor"
-  link_deps = [ ":source_set" ]
-  sources = [ "all_chrome_metrics.proto" ]
+  descriptor_root_source = "all_chrome_metrics.proto"
 }
diff --git a/protos/perfetto/metrics/webview/BUILD.gn b/protos/perfetto/metrics/webview/BUILD.gn
index 683f093..ec2c9c4 100644
--- a/protos/perfetto/metrics/webview/BUILD.gn
+++ b/protos/perfetto/metrics/webview/BUILD.gn
@@ -15,18 +15,13 @@
 import("../../../../gn/proto_library.gni")
 
 perfetto_proto_library("@TYPE@") {
-  proto_generators = [ "source_set" ]
-  deps = [ "..:@TYPE@" ]
+  proto_generators = []
+  import_dirs = [ "${perfetto_protobuf_src_dir}" ]
   sources = [
     "all_webview_metrics.proto",
     "webview_jank_approximation.proto",
   ]
-}
-
-perfetto_proto_library("descriptor") {
-  proto_generators = [ "descriptor" ]
-  import_dirs = [ "${perfetto_protobuf_src_dir}" ]
+  deps = [ "..:@TYPE@" ]
   generate_descriptor = "all_webview_metrics.descriptor"
-  link_deps = [ ":source_set" ]
-  sources = [ "all_webview_metrics.proto" ]
+  descriptor_root_source = "all_webview_metrics.proto"
 }
diff --git a/protos/perfetto/trace/BUILD.gn b/protos/perfetto/trace/BUILD.gn
index 8cf914b..4ecdb18 100644
--- a/protos/perfetto/trace/BUILD.gn
+++ b/protos/perfetto/trace/BUILD.gn
@@ -73,21 +73,11 @@
   ]
 }
 
-# This is only for Bazel build generation.
-group("source_set") {
-  testonly = true
-  public_deps = [
-    ":minimal_source_set",
-    ":non_minimal_source_set",
-  ]
-}
-
 perfetto_proto_library("non_minimal_@TYPE@") {
   proto_generators = [
     "cpp",
     "lite",
     "zero",
-    "source_set",
   ]
   deps = [
     ":minimal_@TYPE@",
@@ -117,11 +107,12 @@
   sources = proto_sources_minimal
 }
 
-perfetto_proto_library("descriptor") {
-  proto_generators = [ "descriptor" ]
+perfetto_proto_library("@TYPE@") {
+  proto_generators = []
+  deps = [ ":non_minimal_@TYPE@" ]
+  sources = []
   generate_descriptor = "trace.descriptor"
-  sources = [ "trace.proto" ]
-  link_deps = [ ":non_minimal_source_set" ]
+  descriptor_root_source = "trace.proto"
 }
 
 # This target exports perfetto trace protos allowing both host and device
@@ -131,11 +122,11 @@
   deps = [ ":lite" ]
 }
 
-perfetto_proto_library("test_extensions_descriptor") {
-  proto_generators = [ "descriptor" ]
-  generate_descriptor = "test_extensions.descriptor"
+perfetto_proto_library("test_extensions_@TYPE@") {
+  proto_generators = []
   sources = [ "test_extensions.proto" ]
-  link_deps = [ "track_event:source_set" ]
+  generate_descriptor = "test_extensions.descriptor"
+  descriptor_root_source = "test_extensions.proto"
 }
 
 if (enable_perfetto_merged_protos_check) {
diff --git a/protos/perfetto/trace/android/BUILD.gn b/protos/perfetto/trace/android/BUILD.gn
index d5e5901..9032877 100644
--- a/protos/perfetto/trace/android/BUILD.gn
+++ b/protos/perfetto/trace/android/BUILD.gn
@@ -60,10 +60,7 @@
 
 # Winscope messages added to TracePacket as extensions
 perfetto_proto_library("winscope_extensions_@TYPE@") {
-  proto_generators = [
-    "zero",
-    "source_set",
-  ]
+  proto_generators = [ "zero" ]
   public_deps = [ ":winscope_common_@TYPE@" ]
   sources = [
     "android_input_event.proto",
@@ -115,30 +112,25 @@
   deps = [ ":winscope_extensions_zero" ]
 }
 
-perfetto_proto_library("winscope_descriptor") {
-  proto_generators = [ "descriptor" ]
-  generate_descriptor = "winscope.descriptor"
-  link_deps = [
-    ":winscope_extensions_source_set",
-    ":winscope_regular_source_set",
-  ]
+perfetto_proto_library("winscope_@TYPE@") {
+  proto_generators = []
   sources = [ "winscope.proto" ]
+  deps = [
+    ":winscope_extensions_@TYPE@",
+    ":winscope_regular_@TYPE@",
+  ]
   import_dirs = [ "${perfetto_protobuf_src_dir}" ]
+  generate_descriptor = "winscope.descriptor"
+  descriptor_root_source = "winscope.proto"
 }
 
 # Android track_event extensions
 perfetto_proto_library("android_track_event_@TYPE@") {
-  proto_generators = [ "source_set" ]
-  public_deps = [ "../track_event:@TYPE@" ]
-  sources = [ "android_track_event.proto" ]
-}
-
-perfetto_proto_library("android_track_event_@TYPE@") {
-  proto_generators = [ "descriptor" ]
-  generate_descriptor = "android_track_event.descriptor"
   sources = [ "android_track_event.proto" ]
   deps = [ "../track_event:@TYPE@" ]
-  link_deps = [ ":android_track_event_source_set" ]
+
+  generate_descriptor = "android_track_event.descriptor"
+  descriptor_root_source = "android_track_event.proto"
 
   # This is the descriptor for an extension. It shouldn't include the descriptor
   # for the base message as well.
diff --git a/protos/perfetto/trace/etw/BUILD.gn b/protos/perfetto/trace/etw/BUILD.gn
index f22514c..fb4bf93 100644
--- a/protos/perfetto/trace/etw/BUILD.gn
+++ b/protos/perfetto/trace/etw/BUILD.gn
@@ -18,12 +18,8 @@
 
 perfetto_proto_library("@TYPE@") {
   sources = etw_proto_names
-}
-
-if (perfetto_build_standalone) {
-  perfetto_proto_library("descriptor") {
-    proto_generators = [ "descriptor" ]
+  if (perfetto_build_standalone) {
     generate_descriptor = "etw.descriptor"
-    sources = [ "etw_event_bundle.proto" ]
+    descriptor_root_source = "etw_event_bundle.proto"
   }
 }
diff --git a/protos/perfetto/trace/ftrace/BUILD.gn b/protos/perfetto/trace/ftrace/BUILD.gn
index 2b6182d..6418223 100644
--- a/protos/perfetto/trace/ftrace/BUILD.gn
+++ b/protos/perfetto/trace/ftrace/BUILD.gn
@@ -18,12 +18,8 @@
 
 perfetto_proto_library("@TYPE@") {
   sources = ftrace_proto_names
-}
-
-if (perfetto_build_standalone) {
-  perfetto_proto_library("descriptor") {
-    proto_generators = [ "descriptor" ]
+  if (perfetto_build_standalone) {
     generate_descriptor = "ftrace.descriptor"
-    sources = [ "ftrace_event_bundle.proto" ]
+    descriptor_root_source = "ftrace_event_bundle.proto"
   }
 }
diff --git a/protos/perfetto/trace/track_event/BUILD.gn b/protos/perfetto/trace/track_event/BUILD.gn
index 0d2749b..a7467d7 100644
--- a/protos/perfetto/trace/track_event/BUILD.gn
+++ b/protos/perfetto/trace/track_event/BUILD.gn
@@ -44,44 +44,6 @@
     "track_descriptor.proto",
     "track_event.proto",
   ]
-}
-
-config("descriptor_inputs_config") {
-  inputs = [
-    "debug_annotation.proto",
-    "log_message.proto",
-    "task_execution.proto",
-    "chrome_active_processes.proto",
-    "chrome_application_state_info.proto",
-    "chrome_compositor_scheduler_state.proto",
-    "chrome_content_settings_event_info.proto",
-    "chrome_frame_reporter.proto",
-    "chrome_histogram_sample.proto",
-    "chrome_keyed_service.proto",
-    "chrome_latency_info.proto",
-    "chrome_legacy_ipc.proto",
-    "chrome_message_pump.proto",
-    "chrome_mojo_event_info.proto",
-    "chrome_renderer_scheduler_state.proto",
-    "chrome_user_event.proto",
-    "chrome_window_handle_event_info.proto",
-    "screenshot.proto",
-    "source_location.proto",
-  ]
-}
-
-group("descriptor_inputs") {
-  public_configs = [ ":descriptor_inputs_config" ]
-}
-
-perfetto_proto_library("descriptor") {
-  proto_generators = [ "descriptor" ]
   generate_descriptor = "track_event.descriptor"
-  sources = [ "track_event.proto" ]
-
-  # TODO(lalitm): remove this target when we found better way to propagate
-  # indirect input deps.
-  proto_deps = [ ":descriptor_inputs" ]
-
-  link_deps = [ ":source_set" ]
+  descriptor_root_source = "track_event.proto"
 }
diff --git a/protos/perfetto/trace_processor/BUILD.gn b/protos/perfetto/trace_processor/BUILD.gn
index f514f42..1d25669 100644
--- a/protos/perfetto/trace_processor/BUILD.gn
+++ b/protos/perfetto/trace_processor/BUILD.gn
@@ -20,7 +20,6 @@
     "cpp",
     "lite",
     "zero",
-    "source_set",
   ]
   deps = [ "../common:@TYPE@" ]  # needed for descriptor.proto.
   sources = []
@@ -29,16 +28,14 @@
   }
 }
 
-perfetto_proto_library("stack_descriptor") {
-  proto_generators = [ "descriptor" ]
-  generate_descriptor = "stack.descriptor"
+perfetto_proto_library("stack_@TYPE@") {
+  proto_generators = []
   sources = [ "stack.proto" ]
+  generate_descriptor = "stack.descriptor"
+  descriptor_root_source = "stack.proto"
 }
 
 perfetto_proto_library("metrics_impl_@TYPE@") {
-  proto_generators = [
-    "zero",
-    "source_set",
-  ]
+  proto_generators = [ "zero" ]
   sources = [ "metrics_impl.proto" ]
 }
diff --git a/protos/third_party/chromium/BUILD.gn b/protos/third_party/chromium/BUILD.gn
index 4cd5d12..c6e47ad 100644
--- a/protos/third_party/chromium/BUILD.gn
+++ b/protos/third_party/chromium/BUILD.gn
@@ -5,47 +5,9 @@
 perfetto_proto_library("@TYPE@") {
   sources = chrome_track_event_sources
   public_deps = [ "../../perfetto/trace/track_event:@TYPE@" ]
-}
 
-config("descriptor_inputs_config") {
-  inputs = [
-    "../../perfetto/trace/track_event/track_event.proto",
-    "../../perfetto/trace/track_event/debug_annotation.proto",
-    "../../perfetto/trace/track_event/source_location.proto",
-    "../../perfetto/trace/track_event/log_message.proto",
-    "../../perfetto/trace/track_event/task_execution.proto",
-    "../../perfetto/trace/track_event/chrome_active_processes.proto",
-    "../../perfetto/trace/track_event/chrome_application_state_info.proto",
-    "../../perfetto/trace/track_event/chrome_compositor_scheduler_state.proto",
-    "../../perfetto/trace/track_event/chrome_content_settings_event_info.proto",
-    "../../perfetto/trace/track_event/chrome_frame_reporter.proto",
-    "../../perfetto/trace/track_event/chrome_histogram_sample.proto",
-    "../../perfetto/trace/track_event/chrome_keyed_service.proto",
-    "../../perfetto/trace/track_event/chrome_latency_info.proto",
-    "../../perfetto/trace/track_event/chrome_legacy_ipc.proto",
-    "../../perfetto/trace/track_event/chrome_message_pump.proto",
-    "../../perfetto/trace/track_event/chrome_mojo_event_info.proto",
-    "../../perfetto/trace/track_event/chrome_renderer_scheduler_state.proto",
-    "../../perfetto/trace/track_event/chrome_user_event.proto",
-    "../../perfetto/trace/track_event/chrome_window_handle_event_info.proto",
-    "../../perfetto/trace/track_event/screenshot.proto",
-  ]
-}
-
-group("descriptor_inputs") {
-  public_configs = [ ":descriptor_inputs_config" ]
-}
-
-perfetto_proto_library("@TYPE@") {
-  proto_generators = [ "descriptor" ]
-  sources = chrome_track_event_sources
   generate_descriptor = "chrome_track_event.descriptor"
-
-  # TODO(lalitm): remove this target when we found better way to propagate
-  # indirect input deps.
-  proto_deps = [ ":descriptor_inputs" ]
-
-  link_deps = [ ":source_set" ]
+  descriptor_root_source = "chrome_track_event.proto"
 
   # When rolled into Chrome, extension descriptor is going to be linked into
   # binary, therefore increasing its size. Including imports means that the
diff --git a/protos/third_party/pprof/BUILD.gn b/protos/third_party/pprof/BUILD.gn
index f38894c..9b8daa2 100644
--- a/protos/third_party/pprof/BUILD.gn
+++ b/protos/third_party/pprof/BUILD.gn
@@ -18,13 +18,8 @@
   proto_generators = [
     "zero",
     "cpp",
-    "source_set",
   ]
   sources = [ "profile.proto" ]
-}
-
-perfetto_proto_library("profile_descriptor") {
-  proto_generators = [ "descriptor" ]
   generate_descriptor = "profile.descriptor"
-  sources = [ "profile.proto" ]
+  descriptor_root_source = "profile.proto"
 }
diff --git a/protos/third_party/statsd/BUILD.gn b/protos/third_party/statsd/BUILD.gn
index 5558d7b..5a1889e 100644
--- a/protos/third_party/statsd/BUILD.gn
+++ b/protos/third_party/statsd/BUILD.gn
@@ -15,10 +15,7 @@
 import("../../../gn/proto_library.gni")
 
 perfetto_proto_library("config_@TYPE@") {
-  proto_generators = [
-    "zero",
-    "source_set",
-  ]
+  proto_generators = [ "zero" ]
   sources = [
     "shell_config.proto",
     "shell_data.proto",
diff --git a/src/perfetto_cmd/BUILD.gn b/src/perfetto_cmd/BUILD.gn
index ccbf07d..4cfe0ea 100644
--- a/src/perfetto_cmd/BUILD.gn
+++ b/src/perfetto_cmd/BUILD.gn
@@ -134,10 +134,7 @@
 }
 
 perfetto_proto_library("protos_@TYPE@") {
-  proto_generators = [
-    "cpp",
-    "source_set",
-  ]
+  proto_generators = [ "cpp" ]
   sources = [ "perfetto_cmd_state.proto" ]
   proto_path = perfetto_root_path
 }
diff --git a/src/protozero/BUILD.gn b/src/protozero/BUILD.gn
index d47691e..ebdcc6f 100644
--- a/src/protozero/BUILD.gn
+++ b/src/protozero/BUILD.gn
@@ -104,6 +104,8 @@
     "test/example_proto/test_messages.proto",
     "test/example_proto/upper_import.proto",
   ]
+  generate_descriptor = "test_messages.descriptor"
+  descriptor_root_source = "test/example_proto/test_messages.proto"
   proto_path = perfetto_root_path
 }
 
@@ -117,13 +119,6 @@
   proto_path = perfetto_root_path
 }
 
-perfetto_proto_library("test_messages_descriptor") {
-  proto_generators = [ "descriptor" ]
-  generate_descriptor = "test_messages.descriptor"
-  sources = [ "test/example_proto/test_messages.proto" ]
-  link_deps = [ ":testing_messages_source_set" ]
-}
-
 perfetto_fuzzer_test("protozero_decoder_fuzzer") {
   sources = [ "proto_decoder_fuzzer.cc" ]
   deps = [
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index eac41c0..5666a50 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -247,7 +247,7 @@
         "../../protos/perfetto/trace:descriptor",
         "../../protos/perfetto/trace:test_extensions_descriptor",
         "../../protos/perfetto/trace_processor:stack_descriptor",
-        "../../protos/third_party/pprof:profile_descriptor",
+        "../../protos/third_party/pprof:descriptor",
       ]
     }
   }
@@ -343,7 +343,7 @@
 
 perfetto_cc_proto_descriptor("gen_cc_test_messages_descriptor") {
   descriptor_name = "test_messages.descriptor"
-  descriptor_target = "../protozero:test_messages_descriptor"
+  descriptor_target = "../protozero:testing_messages_descriptor"
 }
 
 source_set("integrationtests") {
diff --git a/tools/gn_utils.py b/tools/gn_utils.py
index 9e32c91..eb1a5c7 100644
--- a/tools/gn_utils.py
+++ b/tools/gn_utils.py
@@ -444,7 +444,8 @@
       target.proto_plugin = proto_target_type
       target.proto_paths.update(self.get_proto_paths(proto_desc))
       target.proto_exports.update(self.get_proto_exports(proto_desc))
-      target.sources.update(proto_desc.get('sources', []))
+      target.sources.update(
+          self.get_proto_sources(proto_target_type, proto_desc))
       assert (all(x.endswith('.proto') for x in target.sources))
     elif target.type == 'source_set':
       self.source_sets[gn_target_name] = target
@@ -536,6 +537,12 @@
     metadata = proto_desc.get('metadata', {})
     return metadata.get('proto_import_dirs', [])
 
+  def get_proto_sources(self, proto_target_type, proto_desc):
+    if proto_target_type == 'source_set':
+      metadata = proto_desc.get('metadata', {})
+      return metadata.get('proto_library_sources', [])
+    return proto_desc.get('sources', [])
+
   def get_proto_target_type(
       self, target: Target) -> Tuple[Optional[str], Optional[Dict]]:
     """ Checks if the target is a proto library and return the plugin.