/* * Copyright 2013-present Facebook, Inc. * * 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. */ package com.facebook.buck.rules; import com.facebook.buck.model.Flavor; import com.facebook.buck.parser.NoSuchBuildTargetException; import com.facebook.buck.rules.coercer.ConstructorArgMarshaller; import com.facebook.buck.util.MoreStrings; import com.google.common.base.CaseFormat; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; /** * The Source of Truth about a {@link BuildRule}, providing mechanisms to expose the arguments that * rules derived from the Buildable take and providing a factory for those BuildRules. It is * expected that instances of this class are stateless. * * @param <T> The object describing the parameters to be passed to the {@link BuildRule}. How this * is processed is described in the class level javadoc of {@link ConstructorArgMarshaller}. */ public interface Description<T> { static final LoadingCache<Class<? extends Description<?>>, BuildRuleType> BUILD_RULE_TYPES_BY_CLASS = CacheBuilder.newBuilder() .build( new CacheLoader<Class<? extends Description<?>>, BuildRuleType>() { @Override public BuildRuleType load(Class<? extends Description<?>> key) throws Exception { return Description.getBuildRuleType(key.getSimpleName()); } }); /** @return The {@link BuildRuleType} being described. */ static BuildRuleType getBuildRuleType(Class<? extends Description<?>> descriptionClass) { return BUILD_RULE_TYPES_BY_CLASS.getUnchecked(descriptionClass); } @SuppressWarnings("unchecked") static BuildRuleType getBuildRuleType(Description<?> description) { return getBuildRuleType((Class<? extends Description<?>>) description.getClass()); } static BuildRuleType getBuildRuleType(String descriptionClassName) { descriptionClassName = MoreStrings.stripPrefix(descriptionClassName, "Abstract").orElse(descriptionClassName); descriptionClassName = MoreStrings.stripSuffix(descriptionClassName, "Description").orElse(descriptionClassName); return BuildRuleType.of( CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, descriptionClassName)); } /** The class of the argument of this Description uses in createBuildRule(). */ Class<T> getConstructorArgType(); /** * Create a {@link BuildRule} for the given {@link BuildRuleParams}. Note that the {@link * com.facebook.buck.model.BuildTarget} referred to in the {@code params} contains the {@link * Flavor} to create. * * @param resolver For querying for build rules by their targets. * @param cellRoots The roots of known cells. * @param args A constructor argument, of type as returned by {@link #getConstructorArgType()}. * @return The {@link BuildRule} that describes the default flavour of the rule being described. */ BuildRule createBuildRule( TargetGraph targetGraph, BuildRuleParams params, BuildRuleResolver resolver, CellPathResolver cellRoots, T args) throws NoSuchBuildTargetException; }