blob: d00603e81b6f596dbd508321a089e82821381033 [file] [log] [blame]
John Caterf0cadba2022-02-17 15:02:08 -08001// Copyright 2022 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.
14
15package com.google.devtools.build.lib.packages;
16
wyv4858cbf2022-05-04 13:56:45 -070017import com.google.devtools.build.lib.cmdline.BazelModuleContext;
John Caterf0cadba2022-02-17 15:02:08 -080018import com.google.devtools.build.lib.cmdline.Label;
19import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
Googler67f22fa2022-06-13 11:26:45 -070020import com.google.devtools.build.lib.cmdline.PackageIdentifier;
John Caterf0cadba2022-02-17 15:02:08 -080021import com.google.devtools.build.lib.cmdline.RepositoryMapping;
22import java.util.HashMap;
23import java.util.Map;
John Caterf0cadba2022-02-17 15:02:08 -080024import net.starlark.java.eval.StarlarkThread;
25
Googler67f22fa2022-06-13 11:26:45 -070026/**
27 * Converts a label literal string into a {@link Label} object, using the appropriate base package
28 * and repo mapping.
Googlerbc1c1de2023-12-19 12:50:44 -080029 *
30 * <p>Instances are not thread-safe, due to an internal cache.
Googler67f22fa2022-06-13 11:26:45 -070031 */
John Caterf0cadba2022-02-17 15:02:08 -080032public class LabelConverter {
33
Googler67f22fa2022-06-13 11:26:45 -070034 /**
Googler835512a2023-08-11 09:32:06 -070035 * Returns a label converter for the given thread, which MUST be currently evaluating Starlark
36 * code in a .bzl file (top-level, macro, rule implementation function, etc.). It uses the package
37 * containing the .bzl file as the base package, and the repo mapping of the repo containing the
38 * .bzl file.
Googler67f22fa2022-06-13 11:26:45 -070039 */
40 public static LabelConverter forBzlEvaluatingThread(StarlarkThread thread) {
Googler6c3e9d52023-08-09 12:12:32 -070041 BazelModuleContext moduleContext = BazelModuleContext.ofInnermostBzlOrThrow(thread);
Googler98853a72022-07-01 04:23:57 -070042 return new LabelConverter(moduleContext.packageContext());
John Caterf0cadba2022-02-17 15:02:08 -080043 }
44
Googler98853a72022-07-01 04:23:57 -070045 private final Label.PackageContext packageContext;
Googler67f22fa2022-06-13 11:26:45 -070046 private final Map<String, Label> labelCache = new HashMap<>();
John Caterf0cadba2022-02-17 15:02:08 -080047
Googler98853a72022-07-01 04:23:57 -070048 public LabelConverter(Label.PackageContext packageContext) {
49 this.packageContext = packageContext;
50 }
51
Googler67f22fa2022-06-13 11:26:45 -070052 /** Creates a label converter using the given base package and repo mapping. */
53 public LabelConverter(PackageIdentifier base, RepositoryMapping repositoryMapping) {
Googler98853a72022-07-01 04:23:57 -070054 this(Label.PackageContext.of(base, repositoryMapping));
John Caterf0cadba2022-02-17 15:02:08 -080055 }
56
Googler67f22fa2022-06-13 11:26:45 -070057 /** Returns the base package identifier that relative labels will be resolved against. */
58 PackageIdentifier getBasePackage() {
Googler98853a72022-07-01 04:23:57 -070059 return packageContext.packageIdentifier();
John Caterf0cadba2022-02-17 15:02:08 -080060 }
61
62 /** Returns the Label corresponding to the input, using the current conversion context. */
63 public Label convert(String input) throws LabelSyntaxException {
64 // Optimization: First check the package-local map, avoiding Label validation, Label
65 // construction, and global Interner lookup. This approach tends to be very profitable
66 // overall, since it's common for the targets in a single package to have duplicate
67 // label-strings across all their attribute values.
68 Label converted = labelCache.get(input);
69 if (converted == null) {
Googler98853a72022-07-01 04:23:57 -070070 converted = Label.parseWithPackageContext(input, packageContext);
John Caterf0cadba2022-02-17 15:02:08 -080071 labelCache.put(input, converted);
72 }
73 return converted;
74 }
75
John Caterf0cadba2022-02-17 15:02:08 -080076 @Override
77 public String toString() {
Googler98853a72022-07-01 04:23:57 -070078 return getBasePackage().toString();
John Caterf0cadba2022-02-17 15:02:08 -080079 }
80}