Propagate response extensions from BlazeRuntime#afterCommand to the CommandService API.

PiperOrigin-RevId: 356763461
diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD
index 3a7a78e..b19e1d0 100644
--- a/src/test/java/com/google/devtools/build/lib/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/BUILD
@@ -434,10 +434,12 @@
         "//src/main/java/com/google/devtools/common/options",
         "//src/main/java/com/google/devtools/common/options:invocation_policy",
         "//src/main/java/net/starlark/java/syntax",
+        "//src/main/protobuf:any_java_proto",
         "//src/main/protobuf:command_line_java_proto",
         "//src/main/protobuf:failure_details_java_proto",
         "//src/main/protobuf:invocation_policy_java_proto",
         "//src/main/protobuf:test_status_java_proto",
+        "//src/main/protobuf:wrappers_java_proto",
         "//src/test/java/com/google/devtools/build/lib/actions/util",
         "//src/test/java/com/google/devtools/build/lib/events:testutil",
         "//src/test/java/com/google/devtools/build/lib/starlark/util",
@@ -454,6 +456,8 @@
         "//third_party:junit4",
         "//third_party:mockito",
         "//third_party:truth",
+        "//third_party/protobuf",
+        "//third_party/protobuf:protobuf_java",
     ],
 )
 
diff --git a/src/test/java/com/google/devtools/build/lib/runtime/BlazeRuntimeTest.java b/src/test/java/com/google/devtools/build/lib/runtime/BlazeRuntimeTest.java
index a92d70a..8e1040e 100644
--- a/src/test/java/com/google/devtools/build/lib/runtime/BlazeRuntimeTest.java
+++ b/src/test/java/com/google/devtools/build/lib/runtime/BlazeRuntimeTest.java
@@ -32,6 +32,10 @@
 import com.google.devtools.common.options.OptionsBase;
 import com.google.devtools.common.options.OptionsParser;
 import com.google.devtools.common.options.OptionsParsingResult;
+import com.google.protobuf.Any;
+import com.google.protobuf.ByteString;
+import com.google.protobuf.BytesValue;
+import com.google.protobuf.StringValue;
 import java.util.Arrays;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -120,6 +124,49 @@
   }
 
   @Test
+  public void resultExtensions() throws Exception {
+    FileSystem fs = new InMemoryFileSystem(DigestHashFunction.SHA256);
+    ServerDirectories serverDirectories =
+        new ServerDirectories(
+            fs.getPath("/install"), fs.getPath("/output"), fs.getPath("/output_user"));
+    BlazeRuntime runtime =
+        new BlazeRuntime.Builder()
+            .addBlazeModule(
+                new BlazeModule() {
+                  @Override
+                  public BuildOptions getDefaultBuildOptions(BlazeRuntime runtime) {
+                    return BuildOptions.builder().build();
+                  }
+                })
+            .setFileSystem(fs)
+            .setProductName("bazel")
+            .setServerDirectories(serverDirectories)
+            .setStartupOptionsProvider(Mockito.mock(OptionsParsingResult.class))
+            .build();
+    BlazeDirectories directories =
+        new BlazeDirectories(
+            serverDirectories, fs.getPath("/workspace"), fs.getPath("/system_javabase"), "blaze");
+    BlazeWorkspace workspace = runtime.initWorkspace(directories, BinTools.empty(directories));
+    CommandEnvironment env =
+        new CommandEnvironment(
+            runtime,
+            workspace,
+            Mockito.mock(EventBus.class),
+            Thread.currentThread(),
+            VersionCommand.class.getAnnotation(Command.class),
+            OptionsParser.builder().optionsClasses(COMMAND_ENV_REQUIRED_OPTIONS).build(),
+            ImmutableList.of(),
+            0L,
+            0L,
+            ImmutableList.of());
+    Any anyFoo = Any.pack(StringValue.of("foo"));
+    Any anyBar = Any.pack(BytesValue.of(ByteString.copyFromUtf8("bar")));
+    env.addResponseExtensions(ImmutableList.of(anyFoo, anyBar));
+    assertThat(runtime.afterCommand(env, BlazeCommandResult.success()).getResponseExtensions())
+        .containsExactly(anyFoo, anyBar);
+  }
+
+  @Test
   public void addsCommandsFromModules() throws Exception {
     FileSystem fs = new InMemoryFileSystem(DigestHashFunction.SHA256);
     ServerDirectories serverDirectories =
diff --git a/src/test/java/com/google/devtools/build/lib/server/GrpcServerTest.java b/src/test/java/com/google/devtools/build/lib/server/GrpcServerTest.java
index 6b04700..d0b73de 100644
--- a/src/test/java/com/google/devtools/build/lib/server/GrpcServerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/server/GrpcServerTest.java
@@ -16,6 +16,7 @@
 import static com.google.common.truth.Truth.assertThat;
 import static org.junit.Assert.assertThrows;
 
+import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.clock.JavaClock;
 import com.google.devtools.build.lib.runtime.BlazeCommandResult;
 import com.google.devtools.build.lib.runtime.CommandDispatcher;
@@ -43,6 +44,8 @@
 import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
 import com.google.protobuf.Any;
 import com.google.protobuf.ByteString;
+import com.google.protobuf.BytesValue;
+import com.google.protobuf.StringValue;
 import io.grpc.ManagedChannel;
 import io.grpc.Server;
 import io.grpc.inprocess.InProcessChannelBuilder;
@@ -236,7 +239,11 @@
             } catch (IOException e) {
               throw new IllegalStateException(e);
             }
-            return BlazeCommandResult.success();
+            return BlazeCommandResult.withResponseExtensions(
+                BlazeCommandResult.success(),
+                ImmutableList.of(
+                    Any.pack(StringValue.of("foo")),
+                    Any.pack(BytesValue.of(ByteString.copyFromUtf8("bar")))));
           }
         };
     createServer(dispatcher);
@@ -255,10 +262,15 @@
     for (int i = 1; i < 11; i++) {
       assertThat(responses.get(i).getFinished()).isFalse();
       assertThat(responses.get(i).getStandardOutput().toByteArray()).isEqualTo(new byte[1024]);
+      assertThat(responses.get(i).getCommandExtensionsList()).isEmpty();
     }
     assertThat(responses.get(11).getFinished()).isTrue();
     assertThat(responses.get(11).getExitCode()).isEqualTo(0);
     assertThat(responses.get(11).hasFailureDetail()).isFalse();
+    assertThat(responses.get(11).getCommandExtensionsList())
+        .containsExactly(
+            Any.pack(StringValue.of("foo")),
+            Any.pack(BytesValue.of(ByteString.copyFromUtf8("bar"))));
   }
 
   @Test