Allow InMemoryNodeEntry implementations to customize creation of DirtyBuildingState.

PiperOrigin-RevId: 312341883
diff --git a/src/main/java/com/google/devtools/build/skyframe/InMemoryNodeEntry.java b/src/main/java/com/google/devtools/build/skyframe/InMemoryNodeEntry.java
index 84c1b6c..dbf6bb1 100644
--- a/src/main/java/com/google/devtools/build/skyframe/InMemoryNodeEntry.java
+++ b/src/main/java/com/google/devtools/build/skyframe/InMemoryNodeEntry.java
@@ -21,6 +21,7 @@
 import com.google.devtools.build.lib.util.GroupedList.GroupedListHelper;
 import com.google.devtools.build.skyframe.KeyToConsolidate.Op;
 import com.google.devtools.build.skyframe.KeyToConsolidate.OpToStoreBare;
+import com.google.errorprone.annotations.ForOverride;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
@@ -490,13 +491,23 @@
     Preconditions.checkState(keepEdges() == KeepEdgesPolicy.ALL, "Not keeping rdeps: %s", this);
   }
 
+  /**
+   * Creates a {@link DirtyBuildingState} for the case where this node is done and is being marked
+   * dirty.
+   */
+  @ForOverride
+  protected DirtyBuildingState createDirtyBuildingStateForDoneNode(
+      DirtyType dirtyType, GroupedList<SkyKey> directDeps, SkyValue value) {
+    return DirtyBuildingState.create(dirtyType, directDeps, value);
+  }
+
   @Override
   public synchronized MarkedDirtyResult markDirty(DirtyType dirtyType) {
     // Can't process a dirty node without its deps.
     assertKeepDeps();
     if (isDone()) {
       dirtyBuildingState =
-          DirtyBuildingState.create(
+          createDirtyBuildingStateForDoneNode(
               dirtyType, GroupedList.create(getCompressedDirectDepsForDoneEntry()), value);
       value = null;
       directDeps = null;