Dirty Package node can still pool intern labels

This change fixes a remaining issue in `LabelPool#getOrWeakIntern`. By changing to get node from graph using `toValue()` method, we are promised to get `PackageValue` even if node is dirty or changed.

PiperOrigin-RevId: 524377579
Change-Id: I69859977751fe4c664828438c3645e21e67c6d9c
diff --git a/src/main/java/com/google/devtools/build/skyframe/InMemoryGraphImpl.java b/src/main/java/com/google/devtools/build/skyframe/InMemoryGraphImpl.java
index dff42c4..edd9852 100644
--- a/src/main/java/com/google/devtools/build/skyframe/InMemoryGraphImpl.java
+++ b/src/main/java/com/google/devtools/build/skyframe/InMemoryGraphImpl.java
@@ -312,13 +312,16 @@
       PackageValue.Key packageKey = PackageValue.key(packageIdentifier);
 
       InMemoryNodeEntry inMemoryNodeEntry = nodeMap.get(packageKey);
-      if (inMemoryNodeEntry == null || !inMemoryNodeEntry.isDone()) {
-        // If we cannot get the InMemoryNodeEntry, or it is not done, values are not available. So
-        // we can only weak intern sample.
+      if (inMemoryNodeEntry == null) {
+        // If we cannot get the InMemoryNodeEntry, just weak intern the sample.
         return interner.weakIntern(sample);
       }
 
       SkyValue value = inMemoryNodeEntry.toValue();
+      if (value == null) {
+        return interner.weakIntern(sample);
+      }
+
       checkState(value instanceof PackageValue, value);
       ImmutableSortedMap<String, Target> targets = ((PackageValue) value).getPackage().getTargets();
       Target target = targets.get(sample.getName());
diff --git a/src/test/java/com/google/devtools/build/lib/cmdline/LabelInternerIntegrationTest.java b/src/test/java/com/google/devtools/build/lib/cmdline/LabelInternerIntegrationTest.java
index 7ab3395..6716572 100644
--- a/src/test/java/com/google/devtools/build/lib/cmdline/LabelInternerIntegrationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/cmdline/LabelInternerIntegrationTest.java
@@ -119,13 +119,39 @@
   }
 
   @Test
+  public void labelInterner_dirtyPackageStillPoolInternLabel() throws Exception {
+    write("hello/BUILD", "cc_binary(name = 'foo', srcs = ['foo.cc'])");
+    write("hello/foo.cc", "int main() {", "  return 0;", "}");
+    buildTarget("//hello:foo");
+
+    InMemoryGraph graph = skyframeExecutor().getEvaluator().getInMemoryGraph();
+    PackageValue.Key packageKey =
+        PackageValue.key(PackageIdentifier.createInMainRepo(/* name= */ "hello"));
+    NodeEntry nodeEntry = graph.get(/* requestor= */ null, Reason.OTHER, packageKey);
+    assertThat(nodeEntry).isNotNull();
+
+    ImmutableSet<Label> targetLabels =
+        ((PackageValue) nodeEntry.toValue())
+            .getPackage().getTargets().values().stream()
+                .map(TargetApi::getLabel)
+                .collect(toImmutableSet());
+
+    nodeEntry.markDirty(DirtyType.DIRTY);
+
+    // Expect `intern` a duplicate instance to return the canonical one stored in the pool.
+    targetLabels.forEach(
+        l ->
+            assertThat(Label.createUnvalidated(l.getPackageIdentifier(), l.getName()))
+                .isSameInstanceAs(l));
+  }
+
+  @Test
   public void labelInterner_removeDirtyPackageStillWeakInternItsLabels() throws Exception {
     write("hello/BUILD", "cc_binary(name = 'foo', srcs = ['foo.cc'])");
     write("hello/foo.cc", "int main() {", "  return 0;", "}");
     buildTarget("//hello:foo");
 
     InMemoryGraph graph = skyframeExecutor().getEvaluator().getInMemoryGraph();
-
     PackageValue.Key packageKey =
         PackageValue.key(PackageIdentifier.createInMainRepo(/* name= */ "hello"));
     NodeEntry nodeEntry = graph.get(/* requestor= */ null, Reason.OTHER, packageKey);