def _transitive_download_remote_libs(self, go_remote_libs, all_known_remote_libs=None):
    """Recursively attempt to resolve / download all remote transitive deps of go_remote_libs.

    Returns a dict<GoRemoteLibrary, set<tuple<str, Address>>>, which maps a go remote library to a
    set of unresolved remote dependencies, each dependency expressed as a tuple containing the
    the import path of the dependency and the expected target address. If all transitive
    dependencies were successfully resolved, returns an empty dict.

    Downloads as many invalidated transitive dependencies as possible, and returns as many
    undeclared dependencies as possible. However, because the dependencies of a remote library
    can only be determined _after_ it has been downloaded, a transitive dependency of an undeclared
    remote library will never be detected.

    Because go_remote_libraries do not declare dependencies (rather, they are inferred), injects
    all successfully resolved transitive dependencies into the build graph.
    """
    if not go_remote_libs:
      return {}

    all_known_remote_libs = all_known_remote_libs or set()
    all_known_remote_libs.update(go_remote_libs)

    resolved_remote_libs = set()
    undeclared_deps = defaultdict(set)
    go_remote_lib_src = self.context.products.get_data('go_remote_lib_src')

    with self.invalidated(go_remote_libs) as invalidation_check:
      # We accumulate mappings from import path to root (e.g., example.org/pkg/foo -> example.org)
      # from all targets in this map, so that targets share as much of this information as
      # possible during this run.
      # We cache these mappings. to avoid repeatedly fetching them over the network via the
      # meta tag protocol. Note that this mapping is unversioned: It's defined as "whatever meta
      # tag is currently being served at the relevant URL", which is inherently independent of
      # the rev of the remote library.  We (and the entire Go ecosystem) assume that this mapping
      # never changes, in practice.
      import_root_map = {}
      for vt in invalidation_check.all_vts:
        import_root_map_path = os.path.join(vt.results_dir, 'pkg_root_map.txt')
        import_root_map.update(self._read_import_root_map_file(import_root_map_path))

        go_remote_lib = vt.target
        gopath = os.path.join(vt.results_dir, 'gopath')
        if not vt.valid:
          self._fetch_pkg(gopath, go_remote_lib.import_path, go_remote_lib.rev)
        # _map_fetched_remote_source() will modify import_root_map.
        self._map_fetched_remote_source(go_remote_lib, gopath, all_known_remote_libs,
                                        resolved_remote_libs, undeclared_deps, import_root_map)
        go_remote_lib_src[go_remote_lib] = os.path.join(gopath, 'src', go_remote_lib.import_path)

        # Cache the mapping against this target's key.  Note that because we accumulate
        # mappings across targets, the file may contain mappings that this target doesn't
        # need or care about (although it will contain all the mappings this target does need).
        # But the file is small, so there's no harm in this redundancy.
        self._write_import_root_map_file(import_root_map_path, import_root_map)

    # Recurse after the invalidated block, so the libraries we downloaded are now "valid"
    # and thus we don't try to download a library twice.
    trans_undeclared_deps = self._transitive_download_remote_libs(resolved_remote_libs,
                                                                  all_known_remote_libs)
    undeclared_deps.update(trans_undeclared_deps)

    return undeclared_deps