public static boolean isPreprocessFlavoredBuildTarget(BuildTarget target) {
   Set<Flavor> flavors = target.getFlavors();
   for (Flavor flavor : flavors) {
     if (flavor.getName().startsWith(PREPROCESS_FLAVOR_PREFIX)) {
       return true;
     }
   }
   return false;
 }
 public static boolean isCompileFlavoredBuildTarget(BuildTarget target) {
   Set<Flavor> flavors = target.getFlavors();
   for (Flavor flavor : flavors) {
     if (flavor.getName().startsWith(COMPILE_FLAVOR_PREFIX)) {
       return true;
     }
   }
   return false;
 }
  /** Only works with thin binaries. */
  private CxxPlatform getCxxPlatformForBuildTarget(BuildTarget target) {
    CxxPlatform cxxPlatform;
    try {
      cxxPlatform = cxxPlatformFlavorDomain.getValue(target.getFlavors()).or(defaultCxxPlatform);
    } catch (FlavorDomainException e) {
      throw new HumanReadableException(e, "%s: %s", target, e.getMessage());
    }

    return cxxPlatform;
  }
  /** Propagate the bundle's platform flavors to its dependents. */
  @Override
  public ImmutableSet<BuildTarget> findDepsForTargetFromConstructorArgs(
      BuildTarget buildTarget,
      Function<Optional<String>, Path> cellRoots,
      AppleBundleDescription.Arg constructorArg) {
    if (!constructorArg.deps.isPresent()) {
      return ImmutableSet.of();
    }

    if (!cxxPlatformFlavorDomain.containsAnyOf(buildTarget.getFlavors())) {
      buildTarget =
          BuildTarget.builder(buildTarget)
              .addAllFlavors(ImmutableSet.of(defaultCxxPlatform.getFlavor()))
              .build();
    }

    Optional<FatBinaryInfo> fatBinaryInfo =
        FatBinaryInfo.create(platformFlavorsToAppleCxxPlatforms, buildTarget);
    CxxPlatform cxxPlatform;
    if (fatBinaryInfo.isPresent()) {
      AppleCxxPlatform appleCxxPlatform = fatBinaryInfo.get().getRepresentativePlatform();
      cxxPlatform = appleCxxPlatform.getCxxPlatform();
    } else {
      cxxPlatform = getCxxPlatformForBuildTarget(buildTarget);
    }

    String platformName = cxxPlatform.getFlavor().getName();
    final Flavor actualWatchFlavor;
    if (ApplePlatform.isSimulator(platformName)) {
      actualWatchFlavor = ImmutableFlavor.builder().name("watchsimulator-i386").build();
    } else if (platformName.startsWith(ApplePlatform.Name.IPHONEOS)
        || platformName.startsWith(ApplePlatform.Name.WATCHOS)) {
      actualWatchFlavor = ImmutableFlavor.builder().name("watchos-armv7k").build();
    } else {
      actualWatchFlavor = ImmutableFlavor.builder().name(platformName).build();
    }

    FluentIterable<BuildTarget> depsExcludingBinary =
        FluentIterable.from(constructorArg.deps.get())
            .filter(Predicates.not(Predicates.equalTo(constructorArg.binary)));

    FluentIterable<BuildTarget> targetsWithPlatformFlavors =
        depsExcludingBinary.filter(BuildTargets.containsFlavors(cxxPlatformFlavorDomain));

    FluentIterable<BuildTarget> targetsWithoutPlatformFlavors =
        depsExcludingBinary.filter(
            Predicates.not(BuildTargets.containsFlavors(cxxPlatformFlavorDomain)));

    FluentIterable<BuildTarget> watchTargets =
        targetsWithoutPlatformFlavors
            .filter(BuildTargets.containsFlavor(WATCH))
            .transform(
                new Function<BuildTarget, BuildTarget>() {
                  @Override
                  public BuildTarget apply(BuildTarget input) {
                    return BuildTarget.builder(input.withoutFlavors(ImmutableSet.of(WATCH)))
                        .addFlavors(actualWatchFlavor)
                        .build();
                  }
                });

    targetsWithoutPlatformFlavors =
        targetsWithoutPlatformFlavors.filter(Predicates.not(BuildTargets.containsFlavor(WATCH)));

    return ImmutableSet.<BuildTarget>builder()
        .addAll(targetsWithPlatformFlavors)
        .addAll(watchTargets)
        .addAll(
            BuildTargets.propagateFlavorDomains(
                buildTarget,
                ImmutableSet.<FlavorDomain<?>>of(cxxPlatformFlavorDomain),
                targetsWithoutPlatformFlavors))
        .build();
  }
  @SuppressWarnings({"rawtypes", "unchecked"})
  private TargetNode<?> createTargetNode(
      BuckEventBus eventBus,
      Cell cell,
      Path buildFile,
      BuildTarget target,
      Map<String, Object> rawNode,
      TargetNodeListener nodeListener) {
    BuildRuleType buildRuleType = parseBuildRuleTypeFromRawRule(cell, rawNode);

    // Because of the way that the parser works, we know this can never return null.
    Description<?> description = cell.getDescription(buildRuleType);

    if (target.isFlavored()) {
      if (description instanceof Flavored) {
        if (!((Flavored) description).hasFlavors(ImmutableSet.copyOf(target.getFlavors()))) {
          throw new HumanReadableException(
              "Unrecognized flavor in target %s while parsing %s%s.",
              target,
              UnflavoredBuildTarget.BUILD_TARGET_PREFIX,
              MorePaths.pathWithUnixSeparators(
                  target.getBasePath().resolve(cell.getBuildFileName())));
        }
      } else {
        LOG.warn(
            "Target %s (type %s) must implement the Flavored interface "
                + "before we can check if it supports flavors: %s",
            target.getUnflavoredBuildTarget(), buildRuleType, target.getFlavors());
        throw new HumanReadableException(
            "Target %s (type %s) does not currently support flavors (tried %s)",
            target.getUnflavoredBuildTarget(), buildRuleType, target.getFlavors());
      }
    }

    Cell targetCell = cell.getCell(target);
    BuildRuleFactoryParams factoryParams =
        new BuildRuleFactoryParams(
            targetCell.getFilesystem(),
            target.withoutCell(),
            new FilesystemBackedBuildFileTree(cell.getFilesystem(), cell.getBuildFileName()),
            targetCell.isEnforcingBuckPackageBoundaries());
    Object constructorArg = description.createUnpopulatedConstructorArg();
    try {
      ImmutableSet.Builder<BuildTarget> declaredDeps = ImmutableSet.builder();
      ImmutableSet.Builder<BuildTargetPattern> visibilityPatterns = ImmutableSet.builder();
      try (SimplePerfEvent.Scope scope =
          SimplePerfEvent.scope(
              eventBus, PerfEventId.of("MarshalledConstructorArg"), "target", target)) {
        marshaller.populate(
            targetCell.getCellRoots(),
            targetCell.getFilesystem(),
            factoryParams,
            constructorArg,
            declaredDeps,
            visibilityPatterns,
            rawNode);
      }
      try (SimplePerfEvent.Scope scope =
          SimplePerfEvent.scope(eventBus, PerfEventId.of("CreatedTargetNode"), "target", target)) {
        Hasher hasher = Hashing.sha1().newHasher();
        hasher.putString(BuckVersion.getVersion(), UTF_8);
        JsonObjectHashing.hashJsonObject(hasher, rawNode);
        synchronized (this) {
          targetsCornucopia.put(target.getUnflavoredBuildTarget(), target);
        }
        TargetNode<?> node =
            new TargetNode(
                hasher.hash(),
                description,
                constructorArg,
                typeCoercerFactory,
                factoryParams,
                declaredDeps.build(),
                visibilityPatterns.build(),
                targetCell.getCellRoots());
        nodeListener.onCreate(buildFile, node);
        return node;
      }
    } catch (NoSuchBuildTargetException | TargetNode.InvalidSourcePathInputException e) {
      throw new HumanReadableException(e);
    } catch (ConstructorArgMarshalException e) {
      throw new HumanReadableException("%s: %s", target, e.getMessage());
    } catch (IOException e) {
      throw new HumanReadableException(e.getMessage(), e);
    }
  }