Compute the set of targets to build for the given targets using a
            breadth-first traversal.

def compute_targets_to_build(self, targets: Iterable[str]) -> Iterable[BuildTarget]:
        """
            Compute the set of targets to build for the given targets using a
            breadth-first traversal.
        """
        normalized_targets = set()
        for target in targets:
            normalized_targets.update(self._normalize_target(target))

        targets_to_parse = deque(normalized_targets)
        targets_seen = set(normalized_targets)
        targets_not_found = []
        build_targets = set()

        while targets_to_parse:
            next_target_string = targets_to_parse.popleft()
            next_target = self._parse_target(next_target_string)
            build_file = self.parser.parse_file(next_target.build_file_directory)
            if next_target.name not in build_file.targets:
                targets_not_found.append(next_target_string)
                continue
            target_to_build = build_file.targets[next_target.name]
            build_targets.add(target_to_build)

            new_targets = [
                dependency
                for dependency in target_to_build.dependencies
                if dependency not in targets_seen
            ]
            targets_to_parse.extend(new_targets)
            targets_seen.update(new_targets)

        if targets_not_found and self.fail_on_unbuilt_target:
            raise BuilderException(
                "Target(s) could not be built: {}".format(", ".join(targets_not_found)),
                targets=targets_not_found,
            )
        return build_targets