blob: 1cc0df1464433b32b50945479ee74a983687e7b5 [file] [log] [blame]
Florian Weikert438ff162016-05-12 08:49:12 +00001// Copyright 2016 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14package com.google.devtools.build.lib.packages;
15
16import com.google.devtools.build.lib.events.Location;
17import com.google.devtools.build.lib.syntax.EvalException;
18
19/**
20 * An enum that represents different types of rule attributes, based on where their values come
21 * from.
22 */
23public enum AttributeValueSource {
24 COMPUTED_DEFAULT("$", true),
25 LATE_BOUND(":", true),
26 DIRECT("$", false);
27
28 private static final String SKYLARK_PREFIX = "_";
29
30 private final String nativePrefix;
31 private final boolean mustHaveSkylarkPrefix;
32
33 /**
34 * Creates a new instance and defines the prefixes for both Skylark and native.
35 *
36 * @param nativePrefix The prefix when converted to a native attribute name.
Florian Weikertea6c82d2016-09-05 12:15:31 +000037 * @param mustHaveSkylarkPrefix Whether the Skylark name must start with {@link
38 * AttributeValueSource#SKYLARK_PREFIX}.
Florian Weikert438ff162016-05-12 08:49:12 +000039 */
40 AttributeValueSource(String nativePrefix, boolean mustHaveSkylarkPrefix) {
41 this.nativePrefix = nativePrefix;
42 this.mustHaveSkylarkPrefix = mustHaveSkylarkPrefix;
43 }
44
45 /**
46 * Throws an {@link EvalException} if the given Skylark name is not valid for this type.
47 */
48 public void validateSkylarkName(String attrSkylarkName, Location location) throws EvalException {
49 if (attrSkylarkName.isEmpty()) {
50 throw new EvalException(location, "Attribute name must not be empty.");
51 }
52
53 if (mustHaveSkylarkPrefix && !attrSkylarkName.startsWith(SKYLARK_PREFIX)) {
54 throw new EvalException(
55 location,
56 String.format(
57 "When an attribute value is a function, the attribute must be private "
cparsonsa56ccbf2017-10-13 14:57:27 +020058 + "(i.e. start with '%s'). Found '%s'",
59 SKYLARK_PREFIX, attrSkylarkName));
Florian Weikert438ff162016-05-12 08:49:12 +000060 }
61 }
62
63 /**
64 * Converts the given Skylark attribute name to a native attribute name for this type, or throws
65 * an {@link EvalException} if the given Skylark name is not valid for this type.
66 */
67 public String convertToNativeName(String attrSkylarkName, Location location)
68 throws EvalException {
69 validateSkylarkName(attrSkylarkName, location);
70 // No need to check for mustHaveSkylarkPrefix since this was already done in
71 // validateSkylarkName().
72 return attrSkylarkName.startsWith(SKYLARK_PREFIX)
73 ? nativePrefix + attrSkylarkName.substring(SKYLARK_PREFIX.length())
74 : attrSkylarkName;
75 }
76}