/* * Copyright 2015-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.keys; import com.facebook.buck.model.BuckVersion; import com.facebook.buck.rules.BuildRule; import com.facebook.buck.rules.RuleKeyAppendable; import com.facebook.buck.rules.RuleKeyObjectSink; import com.google.common.base.Preconditions; import com.google.common.cache.CacheBuilder; import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableCollection; import java.nio.file.Path; public class RuleKeyFieldLoader { private final int seed; private final LoadingCache<Class<? extends BuildRule>, ImmutableCollection<AlterRuleKey>> cache; public RuleKeyFieldLoader(int seed) { this.seed = seed; this.cache = CacheBuilder.newBuilder().build(new ReflectiveAlterKeyLoader()); } public void setFields(RuleKeyObjectSink builder, BuildRule buildRule, RuleKeyType ruleKeyType) { // "." is not a valid first character for a field name, nor a valid character for rule attribute // name and so the following fields will never collide with other stuff. builder.setReflectively(".seed", seed); builder.setReflectively(".name", buildRule.getBuildTarget().getFullyQualifiedName()); builder.setReflectively(".type", buildRule.getType()); builder.setReflectively(".version", BuckVersion.getVersion()); builder.setReflectively(".key_type", ruleKeyType); // We currently cache items using their full buck-out path, so make sure this is reflected in // the rule key. Path buckOutPath = buildRule.getProjectFilesystem().getBuckPaths().getConfiguredBuckOut(); builder.setReflectively(".out", buckOutPath.toString()); // Add in any extra details to the rule key via the rule's `appendToRuleKey` method. buildRule.appendToRuleKey(builder); // We used to require build rules to piggyback on the `RuleKeyAppendable` type to add in // additional details, but have since switched to using a method in the build rule class, so // error out if we see the `RuleKeyAppendable` being used improperly. Preconditions.checkArgument(!(builder instanceof RuleKeyAppendable)); for (AlterRuleKey alterRuleKey : cache.getUnchecked(buildRule.getClass())) { alterRuleKey.amendKey(builder, buildRule); } } }