/* * Copyright 2016-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.io.ArchiveMemberPath; import com.facebook.buck.model.BuildTarget; import com.facebook.buck.rules.BuildRuleType; import com.facebook.buck.rules.BuildTargetSourcePath; import com.facebook.buck.rules.RuleKey; import com.facebook.buck.rules.SourceRoot; import com.facebook.buck.util.sha1.Sha1HashCode; import com.google.common.hash.HashCode; import java.nio.file.Path; import java.util.regex.Pattern; /** * A hasher used for the rule key construction. * * <p><b>Warning:</b> The result of calling any methods after calling {@link #hash} is undefined. * * <p>Chunks of data that are put into the {@link RuleKeyHasher} are delimited. Delimiting details * are implementation dependent, but one common way is to hash the size of the data along with the * data itself, for each operation performed. For example, the following three expressions should * ideally all generate different hash codes: * * <pre>{@code * newHasher().putByte(b1).putByte(b2).putByte(b3).hash() * newHasher().putByte(b1).putBytes(new byte[] { b2, b3 }).hash() * newHasher().putBytes(new byte[] { b1, b2, b3 }).hash() * }</pre> * * Note, Buck hashes both field values and field names (keys) when constructing rule keys. E.g.: * * <pre>{@code * public class myRule implements BuildRule { * @AddToRuleKey * private final int someInt = 42; * } * }</pre> * * should have {@code "someInt"} hashed via {@code putKey}, and similarly {@code 42} hashed via * {@code putNumber}. */ public interface RuleKeyHasher<HASH> { enum Container { TUPLE, LIST, MAP, } enum Wrapper { SUPPLIER, OPTIONAL, EITHER_LEFT, EITHER_RIGHT, BUILD_RULE, APPENDABLE, } /** Puts the field's key (i.e. the name of the field) */ RuleKeyHasher<HASH> putKey(String key); /** Puts the field's value, Java types */ RuleKeyHasher<HASH> putNull(); RuleKeyHasher<HASH> putBoolean(boolean val); RuleKeyHasher<HASH> putNumber(Number val); RuleKeyHasher<HASH> putString(String val); RuleKeyHasher<HASH> putBytes(byte[] bytes); RuleKeyHasher<HASH> putPattern(Pattern pattern); /** Puts the field's value, Buck specific types */ RuleKeyHasher<HASH> putSha1(Sha1HashCode sha1); RuleKeyHasher<HASH> putPath(Path path, HashCode hash); RuleKeyHasher<HASH> putArchiveMemberPath(ArchiveMemberPath path, HashCode hash); RuleKeyHasher<HASH> putNonHashingPath(String path); RuleKeyHasher<HASH> putSourceRoot(SourceRoot sourceRoot); RuleKeyHasher<HASH> putRuleKey(RuleKey ruleKey); RuleKeyHasher<HASH> putBuildRuleType(BuildRuleType buildRuleType); RuleKeyHasher<HASH> putBuildTarget(BuildTarget buildTarget); RuleKeyHasher<HASH> putBuildTargetSourcePath(BuildTargetSourcePath buildTargetSourcePath); /** Puts the container signature */ RuleKeyHasher<HASH> putContainer(Container container, int length); RuleKeyHasher<HASH> putWrapper(Wrapper wrapper); /** Computes the final hash. */ HASH hash(); }