Increase visibility of an InMemoryNodeEntry method

For use in alternate graph implementations.

Also adds some user-friendly methods to StringValue, a SkyValue
implementation used in tests.

--
MOS_MIGRATED_REVID=104899226
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 094d40a..825584e 100644
--- a/src/main/java/com/google/devtools/build/skyframe/InMemoryNodeEntry.java
+++ b/src/main/java/com/google/devtools/build/skyframe/InMemoryNodeEntry.java
@@ -130,8 +130,7 @@
    * The transient state of this entry, after it has been created but before it is done. It allows
    * us to keep the current state of the entry across invalidation and successive evaluations.
    */
-  @VisibleForTesting
-  protected BuildingState buildingState = new BuildingState();
+  @VisibleForTesting @Nullable protected BuildingState buildingState = new BuildingState();
 
   /**
    * Construct a InMemoryNodeEntry. Use ONLY in Skyframe evaluation and graph implementations.
@@ -184,7 +183,7 @@
 
   /**
    * If {@code isDone()}, returns the ordered list of sets of grouped direct dependencies that were
-   * added in {@link addTemporaryDirectDeps}.
+   * added in {@link #addTemporaryDirectDeps}.
    */
   public synchronized Iterable<Iterable<SkyKey>> getGroupedDirectDeps() {
     assertKeepEdges();
@@ -199,7 +198,7 @@
     return ValueWithMetadata.getMaybeErrorInfo(value);
   }
 
-  private synchronized Set<SkyKey> setStateFinishedAndReturnReverseDeps() {
+  protected synchronized Set<SkyKey> setStateFinishedAndReturnReverseDeps() {
     // Get reverse deps that need to be signaled.
     ImmutableSet<SkyKey> reverseDepsToSignal = buildingState.getReverseDepsToSignal();
     REVERSE_DEPS_UTIL.consolidateData(this);
diff --git a/src/test/java/com/google/devtools/build/skyframe/GraphTester.java b/src/test/java/com/google/devtools/build/skyframe/GraphTester.java
index db686b2..04d76db 100644
--- a/src/test/java/com/google/devtools/build/skyframe/GraphTester.java
+++ b/src/test/java/com/google/devtools/build/skyframe/GraphTester.java
@@ -13,10 +13,13 @@
 // limitations under the License.
 package com.google.devtools.build.skyframe;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.events.Event;
 import com.google.devtools.build.lib.util.Pair;
+import com.google.devtools.build.skyframe.SkyFunction.Environment;
 import com.google.devtools.build.skyframe.SkyFunctionException.Transience;
 
 import java.util.Collection;
@@ -308,6 +311,15 @@
     public String toString() {
       return "StringValue: " + getValue();
     }
+
+    public static StringValue of(String string) {
+      return new StringValue(string);
+    }
+
+    public static StringValue from(SkyValue skyValue) {
+      assertThat(skyValue).isInstanceOf(StringValue.class);
+      return (StringValue) skyValue;
+    }
   }
 
   /**
@@ -336,4 +348,14 @@
       return new StringValue(result.toString());
     }
   };
+
+  public static ValueComputer formatter(final SkyKey key, final String format) {
+    return new ValueComputer() {
+      @Override
+      public SkyValue compute(Map<SkyKey, SkyValue> deps, Environment env)
+          throws InterruptedException {
+        return StringValue.of(String.format(format, StringValue.from(deps.get(key)).getValue()));
+      }
+    };
+  }
 }