Import changes for goma server

  - a6135e0847e80da878fee74e1df115d09aaef398 [remoteexec] use bytes.Equal
  - a52f45b457a5e627aaa34e1e7134221b8f34c896 Run with chroot if needed and allowed.
  - 389164d8293b716fbddf91468c4c4e6af07d3fbd mixer: clients5.google.com should not be default
  - a4ef9cd20704d8abf7023deb7723b8564b7c464d descriptor: allow new clang-cl version string
  - 9409d5f7df1f1e0865525cedb5bd93049e12eb8d goma_replay: use oauth2/v2 for tokeninfo
  - cc18352ff9233b7be1215d08c84446c3ac6fa36a goma_replay: add service account support
  - 305013abf6d560d643e2df792e52abdd9b352ee7 try hard not to do multiple DNS requests for the same host
  - cd10dea2c680ea41a0e4acfcdc47188bcd1379ca Fix typos in goma_replay and mixer-dev README
  - cca3bcde3ecaf368b9766725727678adba8b2f88 goma_replay: resolve hostname once
  - 9f6a10623f93760bf71d86055bda907d025b905f use gofmt -s
  - 2165cf292e73a4881d3bb3d7f2be2544efa9d4b1 remoteexec: use run-at-dir.sh if exists on container image.
  - 4d1f6983a108617312b84d9bbbdd1fa8de5e483b cloudbuild: Use default RBE instance for Windows
  - 7eaa7683584c99cbfa950a568664b20cbf4066a7 add buildsetup.sh for docker-less build
  - e885905a4a25c6e7cf268f15a93f30e1f4e7c589 mitigate grpc timeout
  - fffa2c244b55a9f834e1a4d64f7fde411bb6f725 remoteexec_proxy: add -insecure-remoteexec
  - 30df1ff5e37b9d9e7239a259c19b59a5c01257d5 roll cloud.google.com/go 0.38.0 to 0.39.0
  - a84976e9b58a46afdec04db5e20ecd398358dbd7 remoteexec: fix wrong missing input report
  - 78737b28b8afa248441b3921ac7d71d05d44f8c1 roll google.golang.org/api from 0.4.0 to 0.5.0
  - 91624ddad5e3abb02a0ae40d0d6e5d6c877801eb [proto] remove some ptotobuf protos
  - 29677cfa48530035517c12b64b2c49bbfd777e65 update zap to v1.10.0
  - a0419fa35a7622201412b662afba287143358237 [proto] remove unused google api proto

GitOrigin-RevId: a6135e0847e80da878fee74e1df115d09aaef398
Change-Id: Ic1aa40ae7c4fdf71154e5509d2a0843c6e3750d3
diff --git a/auth/acl/checker_test.go b/auth/acl/checker_test.go
index 19757c6..a4640e8 100644
--- a/auth/acl/checker_test.go
+++ b/auth/acl/checker_test.go
@@ -42,22 +42,22 @@
 func TestChecker(t *testing.T) {
 	config := &pb.ACL{
 		Groups: []*pb.Group{
-			&pb.Group{
+			{
 				Id:     "service-account",
 				Emails: []string{"foo@project.iam.gserviceaccount.com"},
 			},
-			&pb.Group{
+			{
 				Id:             "chrome-bot",
 				Emails:         []string{"goma-client@chrome-infra-auth.iam.gserviceaccount.com"},
 				ServiceAccount: "chrome-bot-service-account",
 			},
-			&pb.Group{
+			{
 				Id:             "googler",
 				Audience:       "687418631491-r6m1c3pr0lth5atp4ie07f03ae8omefc.apps.googleusercontent.com",
 				Domains:        []string{"google.com"},
 				ServiceAccount: "googler-service-account",
 			},
-			&pb.Group{
+			{
 				Id:             "contributor",
 				Audience:       "687418631491-r6m1c3pr0lth5atp4ie07f03ae8omefc.apps.googleusercontent.com",
 				Emails:         []string{"foo@gmail.com"},
@@ -82,58 +82,58 @@
 	}
 
 	testCases := map[string]*testData{
-		"service-account": &testData{
+		"service-account": {
 			tokenInfo: &auth.TokenInfo{
 				Email:    "foo@project.iam.gserviceaccount.com",
 				Audience: "123456-xxxxxx.apps.googleusercontent.com",
 			},
 		},
-		"chrome-bot": &testData{
+		"chrome-bot": {
 			tokenInfo: &auth.TokenInfo{
 				Email:    "goma-client@chrome-infra-auth.iam.gserviceaccount.com",
 				Audience: "7890-xxxxxx.apps.googleusercontent.com",
 			},
 		},
-		"googler": &testData{
+		"googler": {
 			tokenInfo: &auth.TokenInfo{
 				Email:    "someone@google.com",
 				Audience: "687418631491-r6m1c3pr0lth5atp4ie07f03ae8omefc.apps.googleusercontent.com",
 			},
 		},
-		"malicious-googler": &testData{
+		"malicious-googler": {
 			tokenInfo: &auth.TokenInfo{
 				Email:    "malicious@google.com",
 				Audience: "687418631491-r6m1c3pr0lth5atp4ie07f03ae8omefc.apps.googleusercontent.com",
 			},
 		},
-		"contributor": &testData{
+		"contributor": {
 			tokenInfo: &auth.TokenInfo{
 				Email:    "foo@gmail.com",
 				Audience: "687418631491-r6m1c3pr0lth5atp4ie07f03ae8omefc.apps.googleusercontent.com",
 			},
 		},
-		"unknown service account": &testData{
+		"unknown service account": {
 			tokenInfo: &auth.TokenInfo{
 				Email:    "unknown-service-account@chrome-infra-auth.iam.gserviceaccount.com",
 				Audience: "7890-xxxxxx.apps.googleusercontent.com",
 			},
 			errCode: codes.PermissionDenied,
 		},
-		"unknown audience": &testData{
+		"unknown audience": {
 			tokenInfo: &auth.TokenInfo{
 				Email:    "someone@google.com",
 				Audience: "187410957766-f28toeml294bk5mm7nr2jn2rup1rvtjj.apps.googleusercontent.com",
 			},
 			errCode: codes.PermissionDenied,
 		},
-		"unknown user": &testData{
+		"unknown user": {
 			tokenInfo: &auth.TokenInfo{
 				Email:    "unknown.user@gmail.com",
 				Audience: "687418631491-r6m1c3pr0lth5atp4ie07f03ae8omefc.apps.googleusercontent.com",
 			},
 			errCode: codes.PermissionDenied,
 		},
-		"contributor2": &testData{
+		"contributor2": {
 			tokenInfo: &auth.TokenInfo{
 				Email:    "contributor@gmail.com",
 				Audience: "687418631491-r6m1c3pr0lth5atp4ie07f03ae8omefc.apps.googleusercontent.com",
@@ -180,7 +180,7 @@
 
 	t.Logf("reject bad googler")
 	config.Groups = append([]*pb.Group{
-		&pb.Group{
+		{
 			Id:       "bad-googler",
 			Audience: "687418631491-r6m1c3pr0lth5atp4ie07f03ae8omefc.apps.googleusercontent.com",
 			Emails:   []string{"malicious@google.com"},
diff --git a/auth/acl/whitelist.go b/auth/acl/whitelist.go
index cfbdb9c..d324350 100644
--- a/auth/acl/whitelist.go
+++ b/auth/acl/whitelist.go
@@ -22,17 +22,17 @@
 func (DefaultWhitelist) Load(ctx context.Context) (*pb.ACL, error) {
 	return &pb.ACL{
 		Groups: []*pb.Group{
-			&pb.Group{
+			{
 				Id:          "chrome-bot",
 				Description: "chromium buildbot service account",
 				Emails:      []string{"goma-client@chrome-infra-auth.iam.gserviceaccount.com"},
 			},
-			&pb.Group{
+			{
 				Id:          "chromium-swarm-dev",
 				Description: "staging chromium-swarm-dev bots. http://b/63818232 http://crbug.com/684735",
 				Emails:      []string{"pool-chrome@chromium-swarm-dev.iam.gserviceaccount.com"},
 			},
-			&pb.Group{
+			{
 				Id:       "googler",
 				Audience: GomaClientClientID,
 				Domains:  []string{"google.com"},
diff --git a/auth/client_test.go b/auth/client_test.go
index d17b767..264d124 100644
--- a/auth/client_test.go
+++ b/auth/client_test.go
@@ -166,7 +166,7 @@
 			Path: "/path",
 		},
 		Header: map[string][]string{
-			"Authorization": []string{authorization},
+			"Authorization": {authorization},
 		},
 	}
 	ch := make(chan chan bool)
@@ -325,7 +325,7 @@
 	email := "example@google.com"
 	a1 := &Auth{
 		cache: map[string]*authInfo{
-			"Bearer test": &authInfo{
+			"Bearer test": {
 				resp: &authpb.AuthResp{
 					Email:     email,
 					ExpiresAt: willExpireInHour,
@@ -340,7 +340,7 @@
 	}
 	testReq := &http.Request{
 		Header: map[string][]string{
-			"Authorization": []string{"Bearer test"},
+			"Authorization": {"Bearer test"},
 		},
 		// this is needed to make trace work without nil access.
 		URL: &url.URL{
diff --git a/auth/service_test.go b/auth/service_test.go
index 125086a..f50717d 100644
--- a/auth/service_test.go
+++ b/auth/service_test.go
@@ -188,7 +188,7 @@
 	s := &Service{
 		CheckToken: checkToken,
 		tokenCache: map[string]*tokenCacheEntry{
-			key: &tokenCacheEntry{
+			key: {
 				TokenInfo: ti,
 				Token:     token,
 			},
diff --git a/backend/grpc.go b/backend/grpc.go
index 8510274..19260af 100644
--- a/backend/grpc.go
+++ b/backend/grpc.go
@@ -86,7 +86,7 @@
 
 // Exec returns http handler for exec request.
 func (g GRPC) Exec() http.Handler {
-	return execrpc.Handler(g.ExecServer, g.httprpcOpts(5*time.Minute)...)
+	return execrpc.Handler(g.ExecServer, g.httprpcOpts(9*time.Minute+50*time.Second)...)
 }
 
 // ByteStream returns http handler for bytestream.
diff --git a/backend/mixer.go b/backend/mixer.go
index b33e474..7419c14 100644
--- a/backend/mixer.go
+++ b/backend/mixer.go
@@ -133,7 +133,7 @@
 	}
 	backend = m.defaultBackend
 	if backend != nil {
-		logger.Infof("backend default")
+		logger.Infof("backend default for %s", key)
 		return backend, true
 	}
 	return nil, false
diff --git a/buildsetup.sh b/buildsetup.sh
new file mode 100755
index 0000000..1babaa8
--- /dev/null
+++ b/buildsetup.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# Copyright 2019 Google Inc. All Rights Reserved.
+
+set -e
+
+sdkdir="$1"
+if [ ! -d "${sdkdir}" ]; then
+  echo "usage: $0 sdkdir" >&2
+  exit 1
+fi
+mkdir -p "${sdkdir}/go/bin"
+
+# assume host has ca-certificates, cur, git and gcc.
+pkg_missing=false
+for pkg in ca-certificates curl git gcc; do
+  if ! dpkg-query -s "$pkg" >/dev/null; then
+    echo "E: $pkg not installed" >&2
+    pkg_missing=true
+  fi
+done
+if $pkg_missing; then
+  echo "E: package(s) missing" >&2
+  exit 1
+fi
+
+# https://repo1.maven.org/maven2/com/google/protobuf/protoc/${protoc}/protoc-${protoc}-linux-x86_64.exe.sha1
+protoc=3.7.0
+protocsha1=b8f4dea2467de954ac0aa399f2d60ea36c73a5ae
+
+echo "${protocsha1} ${sdkdir}/go/bin/protoc" > /tmp/protoc.sha1
+if ! sha1sum --check /tmp/protoc.sha1; then
+  curl -o "${sdkdir}/go/bin/protoc" https://repo1.maven.org/maven2/com/google/protobuf/protoc/${protoc}/protoc-${protoc}-linux-x86_64.exe
+  sha1sum --check /tmp/protoc.sha1
+fi
+chmod a+x "${sdkdir}/go/bin/protoc"
+rm -f /tmp/protoc.sha1
+
+# TODO: use 'go get golang.org/dl/${go}' ?
+go=go1.12.5
+gosha256=aea86e3c73495f205929cfebba0d63f1382c8ac59be081b6351681415f4063cf
+goarchive="${sdkdir}/${go}.linux-amd64.tar.gz"
+echo "${gosha256} ${goarchive}" > "/tmp/${go}.linux-amd64.tar.gz.sha256"
+if ! sha256sum --check "/tmp/${go}.linux-amd64.tar.gz.sha256"; then
+  curl -o "${goarchive}" "https://storage.googleapis.com/golang/${go}.linux-amd64.tar.gz"
+  sha256sum --check "/tmp/${go}.linux-amd64.tar.gz.sha256"
+  tar -C "${sdkdir}" -xzf "${goarchive}"
+fi
+rm -f "/tmp/${go}.linux-amd64.tar.gz.sha256"
+
+echo "I: protoc-${protoc} and ${go} are installed in ${sdkdir}"
+echo "I: set ${sdkdir}/go/bin in \$PATH"
diff --git a/cmd/auth_server/main.go b/cmd/auth_server/main.go
index e152ae0..17225d2 100644
--- a/cmd/auth_server/main.go
+++ b/cmd/auth_server/main.go
@@ -61,7 +61,7 @@
 	configStatusKey = mustTagNewKey("status")
 
 	configViews = []*view.View{
-		&view.View{
+		{
 			Description: "counts acl updates",
 			TagKeys: []tag.Key{
 				configStatusKey,
diff --git a/cmd/exec_server/main.go b/cmd/exec_server/main.go
index 1ee2ff3..0feb6b3 100644
--- a/cmd/exec_server/main.go
+++ b/cmd/exec_server/main.go
@@ -74,7 +74,7 @@
 	configStatusKey = mustTagNewKey("status")
 
 	configViews = []*view.View{
-		&view.View{
+		{
 			Description: "counts toolchain-config updates",
 			TagKeys: []tag.Key{
 				configStatusKey,
@@ -119,11 +119,9 @@
 			Target: &cmdpb.Target{
 				Addr: *remoteexecAddr,
 			},
-			BuildInfo: &cmdpb.BuildInfo{},
-			RemoteexecPlatform: &cmdpb.RemoteexecPlatform{
-				RbeInstanceBasename: rt.RbeInstanceBasename,
-			},
-			Dimensions: rt.PlatformRuntimeConfig.Dimensions,
+			BuildInfo:          &cmdpb.BuildInfo{},
+			RemoteexecPlatform: &cmdpb.RemoteexecPlatform{},
+			Dimensions:         rt.PlatformRuntimeConfig.Dimensions,
 		}
 		for _, p := range rt.Platform.Properties {
 			c.RemoteexecPlatform.Properties = append(c.RemoteexecPlatform.Properties, &cmdpb.RemoteexecPlatform_Property{
diff --git a/cmd/goma_replay/main.go b/cmd/goma_replay/main.go
index 7867666..5bd6fd7 100644
--- a/cmd/goma_replay/main.go
+++ b/cmd/goma_replay/main.go
@@ -15,9 +15,11 @@
 import (
 	"context"
 	"encoding/json"
+	"errors"
 	"flag"
 	"fmt"
 	"io/ioutil"
+	"net"
 	"net/http"
 	"os"
 	"os/signal"
@@ -33,6 +35,8 @@
 	"github.com/golang/protobuf/proto"
 	"go.uber.org/zap"
 	"golang.org/x/oauth2"
+	"golang.org/x/oauth2/google"
+	googleoauth2 "google.golang.org/api/oauth2/v2"
 
 	"go.chromium.org/goma/server/httprpc"
 	"go.chromium.org/goma/server/log"
@@ -141,43 +145,84 @@
 		return nil, "", fmt.Errorf("oauth2 token %s: %v", fname, err)
 	}
 	logger.Debugf("access token: %s", token.AccessToken)
-	resp, err := http.Get(fmt.Sprintf("https://oauth2.googleapis.com/tokeninfo?access_token=%s", token.AccessToken))
+
+	s, err := googleoauth2.NewService(ctx)
 	if err != nil {
-		return nil, "", fmt.Errorf("%s: tokeninfo %v", fname, err)
+		return nil, "", err
 	}
-	defer resp.Body.Close()
-	b, err = ioutil.ReadAll(resp.Body)
+	tokeninfo, err := s.Tokeninfo().Context(ctx).AccessToken(token.AccessToken).Do()
 	if err != nil {
-		return nil, "", fmt.Errorf("%s: tokeninfo body %v", fname, err)
-	}
-	var tokeninfo struct {
-		Email string `json:"email"`
-	}
-	err = json.Unmarshal(b, &tokeninfo)
-	if err != nil {
-		return nil, "", fmt.Errorf("%s: tokeninfo json %v", fname, err)
+		return nil, "", err
 	}
 	return c.Client(ctx, token), tokeninfo.Email, nil
 }
 
+func oauth2ServiceAccountClient(ctx context.Context, fname string) (*http.Client, string, error) {
+	b, err := ioutil.ReadFile(fname)
+	if err != nil {
+		return nil, "", err
+	}
+	c, err := google.JWTConfigFromJSON(b, googleoauth2.UserinfoEmailScope)
+	if err != nil {
+		return nil, "", err
+	}
+	return c.Client(ctx), c.Email, nil
+}
+
 func newClient(ctx context.Context) (*http.Client, string, error) {
 	logger := log.FromContext(ctx)
-	paths := []string{os.Getenv("GOMA_OAUTH2_CONFIG_FILE")}
-	if *asInternal {
-		paths = append(paths, os.ExpandEnv("$HOME/.goma_oauth2_config"))
-	} else {
-		paths = append(paths, os.ExpandEnv("$HOME/.goma_client_oauth2_config"))
-	}
-	for _, p := range paths {
-		logger.Infof("oauth2 config: %s", p)
-		c, email, err := oauth2Client(ctx, p)
+
+	// client http_init.cc: InitHttpClientOptions
+	for _, ca := range []struct {
+		desc      string
+		newClient func(context.Context) (*http.Client, string, error)
+	}{
+		// TODO: GOMA_HTTP_AUTHORIZATION_FILE
+		{
+			desc: "GOMA_OAUTH2_CONFIG_FILE",
+			newClient: func(ctx context.Context) (*http.Client, string, error) {
+				fname := os.Getenv("GOMA_OAUTH2_CONFIG_FILE")
+				if fname == "" {
+					return nil, "", errors.New("no GOMA_OAUTH2_CONFIG_FILE")
+				}
+				logger.Infof("oauth2 config: %s", fname)
+				return oauth2Client(ctx, fname)
+			},
+		},
+		{
+			desc: "GOMA_SERVICE_ACCOUNT_JSON_FILE",
+			newClient: func(ctx context.Context) (*http.Client, string, error) {
+				fname := os.Getenv("GOMA_SERVICE_ACCOUNT_JSON_FILE")
+				if fname == "" {
+					return nil, "", errors.New("no GOMA_SERVICE_ACCOUNT_JSON_FILE")
+				}
+				logger.Infof("service account: %s", fname)
+				return oauth2ServiceAccountClient(ctx, fname)
+			},
+		},
+		// TODO: GOMA_USE_GCE_SERVICE_ACCOUNT
+		// TODO: LUCI_CONTEXT
+		{
+			desc: "default goma oauth2 config file",
+			newClient: func(ctx context.Context) (*http.Client, string, error) {
+				fname := os.ExpandEnv("$HOME/.goma_client_oauth2_config")
+				if *asInternal {
+					fname = os.ExpandEnv("$HOME/.goma_oauth2_config")
+				}
+				logger.Infof("oauth2 config: %s", fname)
+				return oauth2Client(ctx, fname)
+			},
+		},
+	} {
+		logger.Infof("client auth %s", ca.desc)
+		c, email, err := ca.newClient(ctx)
 		if err != nil {
-			logger.Warnf("oauth2 config %s: %v", p, err)
+			logger.Warnf("client auth %s: %v", ca.desc, err)
 			continue
 		}
 		return c, email, nil
 	}
-	return nil, "", fmt.Errorf("no goma oauth2 config avaialble: %s", paths)
+	return nil, "", errors.New("no goma auth avaialble")
 }
 
 type target struct {
@@ -230,6 +275,48 @@
 	return t, nil
 }
 
+type dialer struct {
+	d     *net.Dialer
+	mu    sync.Mutex
+	addrs map[string]string
+}
+
+func (d *dialer) resolve(ctx context.Context, host string) (string, error) {
+	if a, ok := d.addrs[host]; ok {
+		return a, nil
+	}
+	logger := log.FromContext(ctx)
+	addrs, err := net.LookupHost(host)
+	if err != nil {
+		logger.Warnf("resolve failed %q: %q", host, err)
+		return "", err
+	}
+	logger.Infof("resolve %q => %q", host, addrs[0])
+	d.mu.Lock()
+	d.addrs[host] = addrs[0]
+	d.mu.Unlock()
+	return addrs[0], nil
+}
+
+func (d *dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
+	host, port, err := net.SplitHostPort(address)
+	if err != nil {
+		return nil, err
+	}
+	addr, err := d.resolve(ctx, host)
+	if err != nil {
+		return nil, err
+	}
+	for i := 0; i < 5; i++ {
+		conn, err := d.d.DialContext(ctx, network, net.JoinHostPort(addr, port))
+		if err != nil {
+			continue
+		}
+		return conn, nil
+	}
+	return nil, fmt.Errorf("too many retry to dial to %s:%s", network, address)
+}
+
 func main() {
 	flag.Parse()
 	ctx := context.Background()
@@ -252,6 +339,24 @@
 		logger.Errorf(format, args...)
 	}
 
+	d := &dialer{
+		d: &net.Dialer{
+			Timeout:   30 * time.Second,
+			KeepAlive: 30 * time.Second,
+		},
+		addrs: make(map[string]string),
+	}
+
+	// https://golang.org/pkg/net/http/#RoundTripper
+	http.DefaultTransport = &http.Transport{
+		Proxy:                 http.ProxyFromEnvironment,
+		DialContext:           d.DialContext,
+		MaxIdleConns:          100,
+		IdleConnTimeout:       90 * time.Second,
+		TLSHandshakeTimeout:   10 * time.Second,
+		ExpectContinueTimeout: 1 * time.Second,
+	}
+
 	c, email, err := newClient(ctx)
 	if err != nil {
 		fatalf("client: %v", err)
@@ -262,6 +367,11 @@
 		fatalf("target: %v", err)
 	}
 	fmt.Println("target:", targ)
+	// Warm up the resolver cache
+	_, err = d.resolve(ctx, targ.host)
+	if err != nil {
+		fatalf("resolver warm up: %v", err)
+	}
 	reqs, err := loadRequestData(ctx, *dataSourceDir)
 	if err != nil {
 		fatalf("request data: %v", err)
diff --git a/cmd/remoteexec_proxy/main.go b/cmd/remoteexec_proxy/main.go
index 395d284..05e3aff 100644
--- a/cmd/remoteexec_proxy/main.go
+++ b/cmd/remoteexec_proxy/main.go
@@ -65,6 +65,7 @@
 	whitelistedUsers       = flag.String("whitelisted-users", "", "comma separated list of whitelisted user. if empty, current user is allowed.")
 	serviceAccountJSON     = flag.String("service-account-json", "", "service account json, used to talk to RBE and cloud storage (if --file-cache-bucket is used)")
 	platformContainerImage = flag.String("platform-container-image", "", "docker uri of platform container image")
+	insecureRemoteexec     = flag.Bool("insecure-remoteexec", false, "insecure grpc for remoteexec API")
 
 	fileCacheBucket = flag.String("file-cache-bucket", "", "file cache bucking store bucket")
 
@@ -142,7 +143,7 @@
 
 	return &authpb.ACL{
 		Groups: []*authpb.Group{
-			&authpb.Group{
+			{
 				Id:             "user",
 				Audience:       gomaClientClientID,
 				Emails:         a.whitelistedUser,
@@ -293,10 +294,16 @@
 		},
 	}
 
-	reConn, err := grpc.DialContext(ctx, *remoteexecAddr,
+	opts := []grpc.DialOption{
 		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})),
 		grpc.WithStatsHandler(&ocgrpc.ClientHandler{}),
-	)
+	}
+	if *insecureRemoteexec {
+		opts[0] = grpc.WithInsecure()
+		logger.Warnf("use insecrure remoteexec API")
+	}
+
+	reConn, err := grpc.DialContext(ctx, *remoteexecAddr, opts...)
 	if err != nil {
 		logger.Fatal(err)
 	}
diff --git a/command/configmap.go b/command/configmap.go
index 4546bb2..9289d85 100644
--- a/command/configmap.go
+++ b/command/configmap.go
@@ -432,7 +432,6 @@
 	if err != nil {
 		return nil, err
 	}
-	platform.RbeInstanceBasename = rc.RbeInstanceBasename
 	mergePlatformProperties(platform, rc.Platform)
 
 	confs, err := loadConfigs(ctx, c.StorageClient, uri, rc, platform)
diff --git a/command/descriptor/descriptor.go b/command/descriptor/descriptor.go
index a1c940b..be043c8 100644
--- a/command/descriptor/descriptor.go
+++ b/command/descriptor/descriptor.go
@@ -29,7 +29,7 @@
 	clexeVersionRegexp = regexp.MustCompile(`Compiler Version ([0-9\.]+) for`)
 	clexeTargetRegexp  = regexp.MustCompile(`Compiler Version [0-9\.]+ for (x\d+)`)
 
-	clangclExpectedVersionRegexp = regexp.MustCompile(`clang\s+version\s+\d+\.\d+\.\d+\s+\(trunk\s+\d+\)`)
+	clangclExpectedVersionRegexp = regexp.MustCompile(`clang\s+version\s+\d+\.\d+\.\d+\s+\([^)]*\)`)
 	clangclExpectedTargetRegexp  = regexp.MustCompile(`Target:\s+\.*`)
 )
 
@@ -664,6 +664,11 @@
 //   clang version 6.0.0 (trunk 308728)
 //   Target: x86_64-pc-windows-msvc
 //
+//   clang version 9.0.0 (https://github.com/llvm/llvm-project/ 67510fac36d27b2e22c7cd955fc167136b737b93)
+//   Target: x86_64-pc-windows-msvc
+//   Thread model: posix
+//   InstalledDir: /var/tmp/clang/third_party/llvm-build/Release+Asserts/bin
+//
 // Note that endline might be CRLF.
 func ClangClVersion(out []byte) (string, error) {
 	lines := bytes.SplitN(out, []byte("\n"), 2)
diff --git a/command/descriptor/descriptor_test.go b/command/descriptor/descriptor_test.go
index b2c44fe..8c97244 100644
--- a/command/descriptor/descriptor_test.go
+++ b/command/descriptor/descriptor_test.go
@@ -251,6 +251,18 @@
 			out:  "clang version 3.5.0 (trunk 225621)\r\nTarget: i686-pc-windows-msvc",
 			want: "clang version 3.5.0 (trunk 225621)",
 		},
+		{
+			out: `clang version 9.0.0 (https://github.com/llvm/llvm-project/ 67510fac36d27b2e22c7cd955fc167136b737b93)
+Target: x86_64-pc-windows-msvc
+Thread model: posix
+InstalledDir: /var/tmp/clang/third_party/llvm-build/Release+Asserts/bin
+`,
+			want: "clang version 9.0.0 (https://github.com/llvm/llvm-project/ 67510fac36d27b2e22c7cd955fc167136b737b93)",
+		},
+		{
+			out:  "clang version 9.0.0 (https://github.com/llvm/llvm-project/ 67510fac36d27b2e22c7cd955fc167136b737b93)\r\nTarget: x86_64-pc-windows-msvc\r\nThread model: posix\r\nInstalledDir: /var/tmp/clang/third_party/llvm-build/Release+Asserts/bin\r\n",
+			want: "clang version 9.0.0 (https://github.com/llvm/llvm-project/ 67510fac36d27b2e22c7cd955fc167136b737b93)",
+		},
 	} {
 		got, err := ClangClVersion([]byte(tc.out))
 		if err != nil {
@@ -289,6 +301,18 @@
 			out:  "clang version 3.5.0 (trunk 225621)\r\nTarget: i686-pc-windows-msvc\r\n",
 			want: "i686-pc-windows-msvc",
 		},
+		{
+			out: `clang version 9.0.0 (https://github.com/llvm/llvm-project/ 67510fac36d27b2e22c7cd955fc167136b737b93)
+Target: x86_64-pc-windows-msvc
+Thread model: posix
+InstalledDir: /var/tmp/clang/third_party/llvm-build/Release+Asserts/bin
+`,
+			want: "x86_64-pc-windows-msvc",
+		},
+		{
+			out:  "clang version 9.0.0 (https://github.com/llvm/llvm-project/ 67510fac36d27b2e22c7cd955fc167136b737b93)\r\nTarget: x86_64-pc-windows-msvc\r\nThread model: posix\r\nInstalledDir: /var/tmp/clang/third_party/llvm-build/Release+Asserts/bin\r\n",
+			want: "x86_64-pc-windows-msvc",
+		},
 	} {
 		got, err := ClangClTarget([]byte(tc.out))
 		if err != nil {
diff --git a/command/descriptor/relocate_test.go b/command/descriptor/relocate_test.go
index 9fee37b..b971f33 100644
--- a/command/descriptor/relocate_test.go
+++ b/command/descriptor/relocate_test.go
@@ -22,35 +22,35 @@
 		},
 		CmdDir: "/var/opt/chromium_clang_linux/third_party/llvm-build/Release+Asserts",
 		Files: []*pb.FileSpec{
-			&pb.FileSpec{
+			{
 				Path:         "/usr/bin/as",
 				Size:         356952,
 				Hash:         "ffc7f9fee274e30e308577761adc5fe97b2b22403874500a4c9f26517755ec33",
 				IsExecutable: true,
 			},
-			&pb.FileSpec{
+			{
 				Path:         "/usr/bin/objcopy",
 				Size:         220128,
 				Hash:         "e6ddd34643b436bfe1754f2719ac8ec17ff15497091db592e1b4e335f3653291",
 				IsExecutable: true,
 			},
-			&pb.FileSpec{
+			{
 				Path:    "/usr/bin/ld",
 				Symlink: "ld.bfd",
 			},
-			&pb.FileSpec{
+			{
 				Path:         "/usr/bin/ld.bfd",
 				Size:         1050912,
 				Hash:         "850873e6c4def272aea40f906df43bcb5ad6a7343593dde2dcb89e1a0e4cd6f4",
 				IsExecutable: true,
 			},
-			&pb.FileSpec{
+			{
 				Path:         "/usr/bin/nm",
 				Size:         40704,
 				Hash:         "9119a26b9dffd94cf2f87f10ff0baef81f0912a84a920f5f3441b3cfaf59ff2b",
 				IsExecutable: true,
 			},
-			&pb.FileSpec{
+			{
 				Path:         "/usr/bin/strip",
 				Size:         220128,
 				Hash:         "86aa93fd3010abe601c179a4600acbd348b13d76c66f861591c4d9c615687264",
@@ -61,7 +61,7 @@
 	}
 
 	subprogSetups := map[string]*pb.CmdDescriptor_Setup{
-		"/home/goma/work/chrome/src/out/Release/../../third_party/llvm-build/Release+Asserts/lib/libFindBadConstructs.so": &pb.CmdDescriptor_Setup{
+		"/home/goma/work/chrome/src/out/Release/../../third_party/llvm-build/Release+Asserts/lib/libFindBadConstructs.so": {
 			CmdFile: &pb.FileSpec{
 				Path:         "lib/libFindBadConstructs.so",
 				Size:         521748,
@@ -81,47 +81,47 @@
 	}
 
 	want := []*pb.FileSpec{
-		&pb.FileSpec{
+		{
 			Path:         "/home/goma/work/chrome/src/third_party/llvm-build/Release+Asserts/bin/clang++",
 			Size:         86885440,
 			Hash:         "daacc7bcef72015968bfdda381b8ac27fe735d125314ed17d8320dbda89d7be3",
 			IsExecutable: true,
 		},
-		&pb.FileSpec{
+		{
 			Path:         "/usr/bin/as",
 			Size:         356952,
 			Hash:         "ffc7f9fee274e30e308577761adc5fe97b2b22403874500a4c9f26517755ec33",
 			IsExecutable: true,
 		},
-		&pb.FileSpec{
+		{
 			Path:         "/usr/bin/objcopy",
 			Size:         220128,
 			Hash:         "e6ddd34643b436bfe1754f2719ac8ec17ff15497091db592e1b4e335f3653291",
 			IsExecutable: true,
 		},
-		&pb.FileSpec{
+		{
 			Path:    "/usr/bin/ld",
 			Symlink: "ld.bfd",
 		},
-		&pb.FileSpec{
+		{
 			Path:         "/usr/bin/ld.bfd",
 			Size:         1050912,
 			Hash:         "850873e6c4def272aea40f906df43bcb5ad6a7343593dde2dcb89e1a0e4cd6f4",
 			IsExecutable: true,
 		},
-		&pb.FileSpec{
+		{
 			Path:         "/usr/bin/nm",
 			Size:         40704,
 			Hash:         "9119a26b9dffd94cf2f87f10ff0baef81f0912a84a920f5f3441b3cfaf59ff2b",
 			IsExecutable: true,
 		},
-		&pb.FileSpec{
+		{
 			Path:         "/usr/bin/strip",
 			Size:         220128,
 			Hash:         "86aa93fd3010abe601c179a4600acbd348b13d76c66f861591c4d9c615687264",
 			IsExecutable: true,
 		},
-		&pb.FileSpec{
+		{
 			Path:         "/home/goma/work/chrome/src/out/Release/../../third_party/llvm-build/Release+Asserts/lib/libFindBadConstructs.so",
 			Size:         521748,
 			Hash:         "1c5e11d7975e49ab4396570f54f13d71685005a18593be29bf462b51f45954f6",
@@ -149,7 +149,7 @@
 
 	// objdump is relocatable, and it's requested to place at /opt/bin/objdump.
 	subprogSetups := map[string]*pb.CmdDescriptor_Setup{
-		"/opt/bin/objdump": &pb.CmdDescriptor_Setup{
+		"/opt/bin/objdump": {
 			CmdFile: &pb.FileSpec{
 				Path:         "bin/objdump",
 				Size:         2,
@@ -171,13 +171,13 @@
 	// objdump must be included in FileSpec. clang is not relocatable, so it will be included as is.
 	got := cmdFiles
 	want := []*pb.FileSpec{
-		&pb.FileSpec{
+		{
 			Path:         "/usr/bin/clang",
 			Size:         1,
 			Hash:         "a",
 			IsExecutable: true,
 		},
-		&pb.FileSpec{
+		{
 			Path:         "/opt/bin/objdump",
 			Size:         2,
 			Hash:         "b",
diff --git a/exec/inventory.go b/exec/inventory.go
index 412d764..59247f0 100644
--- a/exec/inventory.go
+++ b/exec/inventory.go
@@ -41,7 +41,7 @@
 	// DefaultToolchainViews are the default views provided by this package.
 	// You need to register the view for data to actually be collected.
 	DefaultToolchainViews = []*view.View{
-		&view.View{
+		{
 			Description: `counts toolchain selection. result is "used", "found", "requested" or "missed"`,
 			TagKeys: []tag.Key{
 				selectorKey,
@@ -449,7 +449,7 @@
 		// can be removed.
 		logger.Debugf("toolchain input: command spec: %v", req.CommandSpec)
 		return []*cmdpb.FileSpec{
-			&cmdpb.FileSpec{
+			{
 				Path:         req.CommandSpec.GetLocalCompilerPath(),
 				IsExecutable: true,
 				Size:         req.CommandSpec.GetSize(),
diff --git a/exec/stats.go b/exec/stats.go
index b6c2810..58acb7f 100644
--- a/exec/stats.go
+++ b/exec/stats.go
@@ -26,7 +26,7 @@
 	// DefaultViews are the default views provided by this package.
 	// You need to register the view for data to actually be collected.
 	DefaultViews = []*view.View{
-		&view.View{
+		{
 			Description: "exec request api-error",
 			TagKeys: []tag.Key{
 				apiErrorKey,
@@ -34,7 +34,7 @@
 			Measure:     apiErrors,
 			Aggregation: view.Count(),
 		},
-		&view.View{
+		{
 			Description: `counts toolchain selection. result is "used", "found", "requested" or "missed"`,
 			TagKeys: []tag.Key{
 				selectorKey,
diff --git a/frontend/frontend.go b/frontend/frontend.go
index 94a0dd3..2a68eb3 100644
--- a/frontend/frontend.go
+++ b/frontend/frontend.go
@@ -53,7 +53,7 @@
 	// DefaultViews are the default views provided by this package.
 	// You need to register he view for data to actually be collected.
 	DefaultViews = []*view.View{
-		&view.View{
+		{
 			Name:        "go.chromium.org/goma/server/frontend.ping_count_by_useragent",
 			Description: "ping request count by user-agent",
 			TagKeys: []tag.Key{
diff --git a/go.mod b/go.mod
index a9a3f47..46467c1 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@
 go 1.12
 
 require (
-	cloud.google.com/go v0.38.0
+	cloud.google.com/go v0.39.0
 	contrib.go.opencensus.io/exporter/stackdriver v0.11.0
 	github.com/bazelbuild/remote-apis v0.0.0-20190507145712-5556e9c6153f
 	github.com/fsnotify/fsnotify v1.4.7
@@ -18,13 +18,13 @@
 	go.opencensus.io v0.21.0
 	go.uber.org/atomic v1.3.2 // indirect
 	go.uber.org/multierr v1.1.0 // indirect
-	go.uber.org/zap v1.9.1
+	go.uber.org/zap v1.10.0
 	golang.org/x/build v0.0.0-20190314215453-3ce8d48fad73
 	golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53
 	golang.org/x/oauth2 v0.0.0-20190319182350-c85d3e98c914
 	golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6
-	google.golang.org/api v0.4.0
-	google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873
+	google.golang.org/api v0.5.0
+	google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8
 	google.golang.org/grpc v1.20.1
 	gopkg.in/yaml.v2 v2.2.2 // indirect
 )
diff --git a/go.sum b/go.sum
index 0af150c..bba7956 100644
--- a/go.sum
+++ b/go.sum
@@ -8,6 +8,8 @@
 cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
 cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo=
 cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
+cloud.google.com/go v0.39.0 h1:UgQP9na6OTfp4dsAiz/eFpFA1C6tPdH5wiRdi19tuMw=
+cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts=
 contrib.go.opencensus.io/exporter/ocagent v0.4.9 h1:8ZbMXpyd04/3LILa/9Tzr8N4HzZNj6Vb2xsaSuR4nQI=
 contrib.go.opencensus.io/exporter/ocagent v0.4.9/go.mod h1:ueLzZcP7LPhPulEBukGn4aLh7Mx9YJwpVJ9nL2FYltw=
 contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA=
@@ -196,6 +198,8 @@
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
 go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o=
 go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
 golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
 golang.org/x/build v0.0.0-20190314133821-5284462c4bec/go.mod h1:atTaCNAy0f16Ah5aV1gMSwgiKVHwu/JncqDpuRr7lS4=
@@ -273,6 +277,8 @@
 google.golang.org/api v0.3.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
 google.golang.org/api v0.4.0 h1:KKgc1aqhV8wDPbDzlDtpvyjZFY3vjz85FP7p4wcQUyI=
 google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
+google.golang.org/api v0.5.0 h1:lj9SyhMzyoa38fgFF0oO2T6pjs5IzkLPKfVtxpyCRMM=
+google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -292,6 +298,8 @@
 google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
 google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg=
 google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8 h1:x913Lq/RebkvUmRSdQ8MNb0GZKn+SR1ESfoetcQSeak=
+google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
 google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
 google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
diff --git a/httprpc/server.go b/httprpc/server.go
index 784193f..491fbd4 100644
--- a/httprpc/server.go
+++ b/httprpc/server.go
@@ -334,9 +334,22 @@
 			logger.Errorf("incoming parse error %s: %d %s: %v", r.URL.Path, code, http.StatusText(code), err)
 			return
 		}
+
+		// use short timeout at first, then longer timeout when
+		// deadline exceeded, to mitigate grpc lost response case.
+		// http://b/129647209
+		// assume most call needs less than 1 minute (both exec,
+		// file access),
+		// according to API metrics, 99%ile of Execute API latency
+		// was 33.225 seconds (as of May 15, 2019).
+		// only a few exec call may need longer timeout.
+		// see below if status.Code(err) == codes.DeadlineExceeded case.
+		timeouts := []time.Duration{40 * time.Second, 1 * time.Minute, 3 * time.Minute, 5 * time.Minute}
 		var resp proto.Message
 		err = opt.retry.Do(ctx, func() error {
-			ctx := ctx
+			pctx := ctx
+			ctx, cancel := context.WithTimeout(ctx, timeouts[0])
+			defer cancel()
 			// TODO: hard fail if opt.Auth == nil?
 			if opt.Auth != nil {
 				ctx, err = opt.Auth.Auth(ctx, r)
@@ -354,6 +367,22 @@
 					Err: err,
 				}
 			}
+			if status.Code(err) == codes.DeadlineExceeded && pctx.Err() == nil {
+				// api call is timed out, but caller's context is not.
+				// it would happen
+				// a) timeout was short; api call actually needs more time.
+				// b) api has been finished, but grpc lost response. http://b/129647209
+				// Retry with longer timeout.
+				// if a, expect to succeed for long run with longer timeout.
+				// if b, expect response soon (cache hit).
+				if len(timeouts) > 1 {
+					timeouts = timeouts[1:]
+				}
+				logger.Warnf("retry with longer timeout %s", timeouts[0])
+				return rpc.RetriableError{
+					Err: err,
+				}
+			}
 			return err
 		})
 		if err != nil {
diff --git a/infra/README.md b/infra/README.md
deleted file mode 100644
index 1a6dc7e..0000000
--- a/infra/README.md
+++ /dev/null
@@ -1 +0,0 @@
-This directory contains chrome-infra-specific files.
diff --git a/infra/config/generated/commit-queue.cfg b/infra/config/generated/commit-queue.cfg
deleted file mode 100644
index 1d22b5f..0000000
--- a/infra/config/generated/commit-queue.cfg
+++ /dev/null
@@ -1,34 +0,0 @@
-# Auto-generated by lucicfg.
-# Do not modify manually.
-#
-# For the schema of this file, see Config message:
-#   https://luci-config.appspot.com/schemas/projects:commit-queue.cfg
-
-cq_status_host: "chromium-cq-status.appspot.com"
-config_groups: <
-  gerrit: <
-    url: "https://chromium-review.googlesource.com"
-    projects: <
-      name: "infra/goma/server"
-      ref_regexp: "refs/heads/master"
-    >
-  >
-  verifiers: <
-    gerrit_cq_ability: <
-      committer_list: "project-goma-server-tryjob-access"
-      dry_run_access_list: "project-chromium-tryjob-access"
-    >
-    tryjob: <
-      builders: <
-        name: "goma-server/try/linux_rel"
-      >
-      retry_config: <
-        single_quota: 1
-        global_quota: 2
-        failure_weight: 100
-        transient_failure_weight: 1
-        timeout_weight: 100
-      >
-    >
-  >
->
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg
deleted file mode 100644
index b1d3394..0000000
--- a/infra/config/generated/cr-buildbucket.cfg
+++ /dev/null
@@ -1,30 +0,0 @@
-# Auto-generated by lucicfg.
-# Do not modify manually.
-#
-# For the schema of this file, see BuildbucketCfg message:
-#   https://luci-config.appspot.com/schemas/projects:buildbucket.cfg
-
-buckets: <
-  name: "try"
-  acls: <
-    group: "all"
-  >
-  acls: <
-    role: SCHEDULER
-    group: "project-goma-server-tryjob-access"
-  >
-  swarming: <
-    builders: <
-      name: "linux_rel"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
-      dimensions: "pool:luci.flex.try"
-      recipe: <
-        name: "goma_server"
-        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
-        cipd_version: "refs/heads/master"
-      >
-    >
-  >
->
diff --git a/infra/config/generated/luci-logdog.cfg b/infra/config/generated/luci-logdog.cfg
deleted file mode 100644
index 45d1c90..0000000
--- a/infra/config/generated/luci-logdog.cfg
+++ /dev/null
@@ -1,8 +0,0 @@
-# Auto-generated by lucicfg.
-# Do not modify manually.
-#
-# For the schema of this file, see ProjectConfig message:
-#   https://luci-config.appspot.com/schemas/projects:luci-logdog.cfg
-
-reader_auth_groups: "all"
-writer_auth_groups: "luci-logdog-chromium-writers"
diff --git a/infra/config/generated/luci-milo.cfg b/infra/config/generated/luci-milo.cfg
deleted file mode 100644
index 3e77e21..0000000
--- a/infra/config/generated/luci-milo.cfg
+++ /dev/null
@@ -1,15 +0,0 @@
-# Auto-generated by lucicfg.
-# Do not modify manually.
-#
-# For the schema of this file, see Project message:
-#   https://luci-config.appspot.com/schemas/projects:luci-milo.cfg
-
-consoles: <
-  id: "Try Builders"
-  name: "Try Builders"
-  builders: <
-    name: "buildbucket/luci.goma-server.try/linux_rel"
-  >
-  builder_view_only: true
->
-logo_url: "https://storage.googleapis.com/chrome-infra-public/logo/goma-server-logo.png"
diff --git a/infra/config/generated/project.cfg b/infra/config/generated/project.cfg
deleted file mode 100644
index f15f1a0..0000000
--- a/infra/config/generated/project.cfg
+++ /dev/null
@@ -1,8 +0,0 @@
-# Auto-generated by lucicfg.
-# Do not modify manually.
-#
-# For the schema of this file, see ProjectCfg message:
-#   https://luci-config.appspot.com/schemas/projects:project.cfg
-
-name: "goma-server"
-access: "group:all"
diff --git a/infra/config/main.star b/infra/config/main.star
deleted file mode 100755
index 5ccaac2..0000000
--- a/infra/config/main.star
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/usr/bin/env lucicfg
-
-luci.project(
-    name = "goma-server",
-
-    buildbucket = "cr-buildbucket.appspot.com",
-    logdog = "luci-logdog.appspot.com",
-    milo = "luci-milo.appspot.com",
-    swarming = "chromium-swarm.appspot.com",
-
-    acls = [
-        # This project is publicly readable.
-        acl.entry(
-            roles = [
-                acl.BUILDBUCKET_READER,
-                acl.LOGDOG_READER,
-                acl.PROJECT_CONFIGS_READER,
-                acl.SCHEDULER_READER,
-            ],
-            groups = "all",
-        ),
-        # Allow committers to use CQ and to force-trigger and stop CI builds.
-        acl.entry(
-            roles = [
-                acl.SCHEDULER_OWNER,
-                acl.CQ_COMMITTER,
-            ],
-            groups = "project-goma-server-tryjob-access"
-        ),
-        # Ability to launch CQ dry runs.
-        acl.entry(
-            roles = acl.CQ_DRY_RUNNER,
-            groups = "project-chromium-tryjob-access"
-        ),
-
-        acl.entry(
-            roles = acl.LOGDOG_WRITER,
-            groups = "luci-logdog-chromium-writers"
-        ),
-    ],
-)
-
-luci.milo(logo = "https://storage.googleapis.com/chrome-infra-public/logo/goma-server-logo.png")
-
-# Without this, luci-logdog.cfg won't be made.
-luci.logdog()
-
-luci.cq(status_host = "chromium-cq-status.appspot.com")
-
-luci.bucket(
-    name = "try",
-    acls = [
-        # Allow launching tryjobs directly (in addition to doing it through CQ).
-        acl.entry(
-            roles = acl.BUILDBUCKET_TRIGGERER,
-            groups = "project-goma-server-tryjob-access",
-        ),
-    ]
-)
-
-
-# The Milo builder list with all pre-submit builders, referenced below.
-luci.list_view(
-    name = "Try Builders",
-)
-
-# The CQ group with all pre-submit builders, referenced below.
-luci.cq_group(
-    name = "Main CQ",
-    watch = cq.refset("https://chromium-review.googlesource.com/infra/goma/server"),
-)
-luci.builder(
-    name = "linux_rel",
-    bucket = "try",
-    executable = luci.recipe(
-        name = "goma_server",
-        cipd_package = "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",
-    ),
-    dimensions = {
-        "pool": "luci.flex.try",
-        "os": "Ubuntu-16.04",
-        "cpu": "x86-64",
-    },
-)
-
-# Add to the CQ.
-luci.cq_tryjob_verifier(
-    builder = "try/linux_rel",
-    cq_group = "Main CQ",
-)
-
-# And also to the pre-submit builders list.
-luci.list_view_entry(
-    builder = "try/linux_rel",
-    list_view = "Try Builders",
-)
diff --git a/proto/command/command.pb.go b/proto/command/command.pb.go
index d556416..b0f287f 100644
--- a/proto/command/command.pb.go
+++ b/proto/command/command.pb.go
@@ -860,8 +860,6 @@
 	// This is selector to use this runtime. i.e. if client request contains
 	// the dimentions, this runtime config will be selected.
 	PlatformRuntimeConfig *PlatformRuntimeConfig `protobuf:"bytes,6,opt,name=platform_runtime_config,json=platformRuntimeConfig,proto3" json:"platform_runtime_config,omitempty"`
-	// Basename of RBE instance to use. e.g. "default_instance" or "windows".
-	RbeInstanceBasename string `protobuf:"bytes,7,opt,name=rbe_instance_basename,json=rbeInstanceBasename,proto3" json:"rbe_instance_basename,omitempty"`
 	// Platform is a set of requirements, such as haredware, operting system
 	// for RBE backend.
 	// property files stored in remoteexec-platform/ in the bucket will be
@@ -933,13 +931,6 @@
 	return nil
 }
 
-func (m *RuntimeConfig) GetRbeInstanceBasename() string {
-	if m != nil {
-		return m.RbeInstanceBasename
-	}
-	return ""
-}
-
 func (m *RuntimeConfig) GetPlatform() *Platform {
 	if m != nil {
 		return m.Platform
@@ -1123,80 +1114,80 @@
 func init() { proto.RegisterFile("command/command.proto", fileDescriptor_ce77433d29a243f3) }
 
 var fileDescriptor_ce77433d29a243f3 = []byte{
-	// 1189 bytes of a gzipped FileDescriptorProto
+	// 1191 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xdb, 0x72, 0x1b, 0x45,
-	0x13, 0xfe, 0x65, 0x9d, 0x76, 0x5b, 0x71, 0x22, 0x8f, 0xe3, 0x44, 0xd1, 0x6f, 0x92, 0x20, 0xa8,
-	0x4a, 0x20, 0x20, 0x57, 0x14, 0xaa, 0x38, 0x14, 0x54, 0x2a, 0xb6, 0x43, 0xc5, 0x0e, 0xd8, 0xaa,
-	0xb5, 0x49, 0xe0, 0x6a, 0x6a, 0x76, 0xb7, 0x2d, 0x4d, 0x65, 0x4f, 0xcc, 0x8c, 0x0c, 0xa2, 0x78,
-	0x08, 0x9e, 0x80, 0x3b, 0x1e, 0x81, 0x37, 0xe0, 0x0d, 0x78, 0x16, 0xee, 0xa9, 0x39, 0xec, 0xca,
-	0x07, 0x39, 0x17, 0x5c, 0x69, 0xbb, 0xfb, 0x9b, 0xee, 0xe9, 0xee, 0xaf, 0x7b, 0x04, 0x1b, 0x51,
-	0x9e, 0xa6, 0x2c, 0x8b, 0xb7, 0xdc, 0xef, 0xb0, 0x10, 0xb9, 0xca, 0x49, 0xdb, 0x89, 0xfd, 0x75,
-	0x56, 0xf0, 0xad, 0x49, 0x9e, 0x32, 0x1a, 0x33, 0xc5, 0xac, 0xb5, 0x7f, 0x6f, 0x92, 0xe7, 0x93,
-	0x04, 0xb7, 0x8c, 0x14, 0xce, 0x4e, 0xb6, 0x14, 0x4f, 0x51, 0x2a, 0x96, 0x16, 0x16, 0x30, 0xf8,
-	0x11, 0xbc, 0x23, 0x4c, 0x30, 0x52, 0xb9, 0x20, 0x04, 0x1a, 0x19, 0x4b, 0xb1, 0x57, 0xbb, 0x5f,
-	0x7b, 0xe8, 0x07, 0xe6, 0x9b, 0xf4, 0xa0, 0x7d, 0x8a, 0x42, 0xf2, 0x3c, 0xeb, 0xad, 0x18, 0x75,
-	0x29, 0x92, 0x5b, 0xd0, 0x52, 0x4c, 0x4c, 0x50, 0xf5, 0xea, 0xc6, 0xe0, 0x24, 0x72, 0x0f, 0x3a,
-	0x21, 0xcf, 0x98, 0x98, 0xd3, 0x29, 0x93, 0xd3, 0x5e, 0xc3, 0x18, 0xc1, 0xaa, 0x5e, 0x30, 0x39,
-	0x1d, 0xfc, 0x5d, 0x03, 0xef, 0x6b, 0x9e, 0xe0, 0x51, 0x81, 0x91, 0x8e, 0x59, 0x30, 0x35, 0x2d,
-	0x63, 0xea, 0x6f, 0xad, 0x93, 0xfc, 0x17, 0x34, 0x01, 0xeb, 0x81, 0xf9, 0xd6, 0x3a, 0xe3, 0xce,
-	0xc6, 0x32, 0xdf, 0xe4, 0x3d, 0x58, 0xe5, 0x92, 0xe2, 0xcf, 0x18, 0xcd, 0x14, 0x0b, 0x13, 0x34,
-	0xb1, 0xbc, 0xe0, 0x1a, 0x97, 0xcf, 0x2b, 0x9d, 0x4e, 0x40, 0xce, 0xd3, 0x84, 0x67, 0x6f, 0x7a,
-	0x4d, 0x9b, 0x80, 0x13, 0xc9, 0x1d, 0xf0, 0xb4, 0x1b, 0xfa, 0x06, 0xe7, 0xbd, 0x96, 0x35, 0x69,
-	0xf9, 0x25, 0xce, 0xc9, 0x23, 0x68, 0x84, 0x49, 0x1e, 0xf6, 0xda, 0xf7, 0x6b, 0x0f, 0x3b, 0xa3,
-	0xdb, 0xc3, 0x18, 0x4f, 0x55, 0x9e, 0x27, 0x92, 0xea, 0xfa, 0x0e, 0xf5, 0xe5, 0xb7, 0x93, 0x3c,
-	0x0c, 0x0c, 0x68, 0xbf, 0xe1, 0x79, 0x5d, 0x7f, 0xb0, 0x09, 0xad, 0x63, 0x5b, 0x00, 0x02, 0x0d,
-	0x16, 0xc7, 0xa2, 0x4c, 0x49, 0x7f, 0x0f, 0xfe, 0xa9, 0x81, 0xbf, 0x3d, 0xe3, 0x49, 0xbc, 0x97,
-	0x9d, 0xe4, 0xfa, 0x4e, 0x91, 0x40, 0xa6, 0x72, 0x51, 0x16, 0xd5, 0x89, 0xa4, 0x0f, 0xde, 0x34,
-	0x97, 0xca, 0xb4, 0xc1, 0xa6, 0x5a, 0xc9, 0x64, 0x13, 0xfc, 0x98, 0x0b, 0xd3, 0xaa, 0xb9, 0x2b,
-	0xeb, 0x42, 0x41, 0x3e, 0x03, 0xbf, 0xea, 0xad, 0xc9, 0xb4, 0x33, 0xea, 0x0f, 0x6d, 0xf7, 0x87,
-	0x65, 0xf7, 0x87, 0xc7, 0x25, 0x22, 0x58, 0x80, 0xc9, 0x3b, 0x00, 0x51, 0x1a, 0x53, 0x89, 0xe2,
-	0x14, 0x85, 0x49, 0xd9, 0x0f, 0xfc, 0x28, 0x8d, 0x8f, 0x8c, 0x42, 0x87, 0xd5, 0xb9, 0x47, 0x53,
-	0xc6, 0xb3, 0x9e, 0x67, 0xad, 0x95, 0x62, 0xbf, 0xe1, 0xd5, 0xba, 0x2b, 0xfb, 0x0d, 0xaf, 0xd5,
-	0x6d, 0x07, 0x2d, 0x4d, 0x45, 0xae, 0x02, 0x7f, 0x56, 0x48, 0x25, 0x90, 0xa5, 0x72, 0xf0, 0x5b,
-	0x13, 0x56, 0x77, 0xd2, 0x78, 0x17, 0x65, 0x24, 0x78, 0xa1, 0x33, 0xfc, 0x18, 0x3c, 0xe9, 0x08,
-	0x67, 0x2a, 0xd4, 0x19, 0xad, 0x0d, 0x4b, 0x46, 0x97, 0x4c, 0x0c, 0x2a, 0x08, 0x19, 0x41, 0x53,
-	0xa2, 0x9a, 0x15, 0xa6, 0x50, 0x9d, 0xd1, 0x66, 0x85, 0x3d, 0xe7, 0x75, 0x78, 0xa4, 0x31, 0x81,
-	0x85, 0xea, 0x33, 0x91, 0xc8, 0xa5, 0x34, 0x15, 0xbc, 0xfa, 0xcc, 0x8e, 0xc6, 0x04, 0x16, 0x4a,
-	0x5e, 0xc2, 0x75, 0x4c, 0x67, 0x09, 0x53, 0x3c, 0xcf, 0x68, 0x5e, 0x28, 0x69, 0x28, 0xd1, 0x19,
-	0xbd, 0x7f, 0xc5, 0xe1, 0xe7, 0x25, 0xf8, 0xb0, 0x50, 0x32, 0x58, 0xc5, 0xb3, 0x62, 0xff, 0xcf,
-	0x1a, 0x34, 0xcd, 0x8d, 0xc8, 0x47, 0xe0, 0xe9, 0xda, 0x9e, 0xf0, 0x04, 0x2f, 0x65, 0x5b, 0xce,
-	0x40, 0xd0, 0x8e, 0xd2, 0x58, 0x0b, 0xe4, 0x36, 0xe8, 0x4f, 0x1a, 0xf3, 0x92, 0x17, 0xad, 0x28,
-	0x8d, 0x77, 0xb9, 0x20, 0x0f, 0xa0, 0xa9, 0x5d, 0xe8, 0x8c, 0xea, 0xcb, 0x7d, 0x58, 0x3b, 0xf9,
-	0x12, 0x7c, 0x3d, 0x42, 0x54, 0xcd, 0x0b, 0x3b, 0x0e, 0xd7, 0x47, 0xf7, 0xae, 0xc8, 0x60, 0xcc,
-	0xd4, 0xf4, 0x78, 0x5e, 0x60, 0xe0, 0x15, 0xee, 0xab, 0xff, 0x04, 0x9a, 0xa6, 0x28, 0xe4, 0x43,
-	0x58, 0x8b, 0x12, 0x96, 0x4d, 0x68, 0x86, 0x18, 0x53, 0x37, 0xe6, 0x35, 0x33, 0x5d, 0x37, 0x8c,
-	0xe1, 0x00, 0x31, 0xb6, 0x74, 0xef, 0x8f, 0x61, 0xf5, 0x5c, 0x31, 0xc8, 0x53, 0xd8, 0x14, 0x28,
-	0x0b, 0x8c, 0x14, 0x8d, 0x12, 0x8e, 0x99, 0xa2, 0x3c, 0x8b, 0x92, 0x59, 0x8c, 0x54, 0x07, 0x92,
-	0xce, 0xcf, 0x1d, 0x87, 0xd9, 0x31, 0x90, 0x3d, 0x8b, 0xd0, 0x77, 0x92, 0x83, 0xcf, 0xc1, 0x2b,
-	0x2f, 0x47, 0x36, 0x60, 0xed, 0xbb, 0x83, 0x97, 0x07, 0x87, 0xaf, 0x0f, 0xe8, 0xf8, 0xd9, 0xf1,
-	0x0b, 0x7a, 0xfc, 0xc3, 0xf8, 0x79, 0xf7, 0x7f, 0xc4, 0x87, 0xe6, 0xf8, 0xf0, 0x68, 0xef, 0xfb,
-	0x6e, 0x8d, 0x74, 0xa0, 0xfd, 0x7a, 0xef, 0x60, 0xf7, 0xf0, 0xf5, 0x91, 0x21, 0x62, 0xa3, 0xdb,
-	0xdc, 0x6f, 0x78, 0xcd, 0x6e, 0x2b, 0x30, 0x95, 0xd7, 0xad, 0x0c, 0x3a, 0x05, 0x8b, 0xde, 0xb0,
-	0x09, 0x6a, 0x69, 0xf0, 0x57, 0x0d, 0x48, 0x80, 0x69, 0xae, 0x50, 0x6f, 0x8e, 0x71, 0xc2, 0xd4,
-	0x49, 0x2e, 0x52, 0xb2, 0x0b, 0x50, 0x88, 0xbc, 0x40, 0xa1, 0x38, 0xea, 0x3b, 0xd6, 0xcf, 0x35,
-	0xff, 0xf2, 0x81, 0xe1, 0xd8, 0xa2, 0xe7, 0xc1, 0x99, 0x73, 0x64, 0x04, 0x1b, 0x22, 0x44, 0xca,
-	0x33, 0xa9, 0x58, 0x16, 0x21, 0x0d, 0x99, 0x44, 0x33, 0xcc, 0xb6, 0x9f, 0xeb, 0x22, 0xc4, 0x3d,
-	0x67, 0xdb, 0x76, 0xa6, 0xfe, 0x27, 0xe0, 0x95, 0xbe, 0x96, 0xae, 0xe0, 0x9b, 0xd0, 0x3c, 0x65,
-	0xc9, 0xac, 0xf4, 0x61, 0x85, 0xc1, 0xef, 0x2b, 0xd0, 0xda, 0xc9, 0xb3, 0x13, 0x3e, 0x21, 0x0f,
-	0xaa, 0x4d, 0x6c, 0x29, 0x76, 0xa3, 0xba, 0xb6, 0x6d, 0x51, 0xb5, 0x9a, 0x1f, 0x03, 0x84, 0x7a,
-	0x09, 0x51, 0x9e, 0x9d, 0xe4, 0x6e, 0x3a, 0x48, 0x05, 0xae, 0xf6, 0x53, 0xe0, 0x87, 0xd5, 0xaa,
-	0xfa, 0x0a, 0xae, 0x1b, 0x4a, 0x56, 0xbc, 0x31, 0xac, 0xea, 0x8c, 0x6e, 0x2d, 0x67, 0x55, 0xb0,
-	0x1a, 0x9d, 0x9b, 0xf6, 0x6f, 0x60, 0x5d, 0x54, 0xa5, 0xa3, 0x85, 0xab, 0x9d, 0xdb, 0x4f, 0xff,
-	0x7f, 0x4b, 0x79, 0x03, 0x22, 0x2e, 0xf7, 0xe8, 0x2e, 0x40, 0xcc, 0x53, 0xcc, 0xf4, 0xfb, 0xa3,
-	0x07, 0xb4, 0xae, 0x5f, 0x96, 0x85, 0x66, 0xbf, 0xe1, 0xad, 0x74, 0xeb, 0x41, 0x93, 0xa7, 0x6c,
-	0x82, 0x83, 0x5f, 0xc1, 0xab, 0x0e, 0x7e, 0xb1, 0xa4, 0xb9, 0xfd, 0x2a, 0xfa, 0x5b, 0x5b, 0xfa,
-	0x1f, 0xdb, 0xf3, 0x47, 0x1d, 0x56, 0x83, 0x59, 0xa6, 0xb7, 0xac, 0xeb, 0xd2, 0xb2, 0xb3, 0xef,
-	0xc2, 0x35, 0xbd, 0x76, 0x79, 0x84, 0xd4, 0x3c, 0x19, 0xd6, 0x45, 0xc7, 0xe9, 0x9e, 0xc5, 0xb1,
-	0x20, 0xaf, 0xe0, 0x76, 0x59, 0x36, 0x2a, 0xac, 0x43, 0x1a, 0x19, 0x8f, 0x6e, 0x43, 0xdd, 0xbd,
-	0x94, 0xc7, 0xb9, 0xb8, 0xc1, 0x46, 0xb1, 0x4c, 0x7d, 0x35, 0x53, 0xdb, 0x57, 0x32, 0x55, 0xef,
-	0xee, 0xaa, 0x85, 0xde, 0x85, 0x6d, 0x56, 0x05, 0xaf, 0x20, 0xe4, 0x11, 0xac, 0xb1, 0x24, 0xc9,
-	0x7f, 0xc2, 0x98, 0x16, 0x02, 0x35, 0xa7, 0x94, 0xdd, 0x60, 0x7e, 0xd0, 0x75, 0x86, 0x71, 0xa9,
-	0x27, 0x8f, 0xe1, 0x66, 0xcc, 0xe5, 0x65, 0x7c, 0xc3, 0xe0, 0xd7, 0x17, 0xb6, 0xc5, 0x91, 0x6d,
-	0x38, 0xa3, 0xa6, 0xee, 0x22, 0xb2, 0xd7, 0xbc, 0xb0, 0x23, 0xab, 0x57, 0x85, 0x2c, 0xd0, 0x3b,
-	0x0e, 0x3c, 0xf8, 0x14, 0x36, 0x96, 0x96, 0xed, 0x02, 0xd7, 0x6a, 0x17, 0xb9, 0x36, 0x78, 0x0a,
-	0xbe, 0x45, 0x7e, 0xcb, 0xf4, 0x8b, 0xe3, 0xb9, 0xde, 0x94, 0xec, 0x5a, 0xcc, 0xc7, 0xf9, 0x6e,
-	0x54, 0xb8, 0xc1, 0x2b, 0x00, 0xa7, 0x43, 0x69, 0x1e, 0x61, 0xf7, 0xc7, 0x8a, 0xf2, 0xd8, 0xf1,
-	0xc0, 0x77, 0x9a, 0xbd, 0x98, 0x7c, 0x00, 0x6d, 0xdb, 0xf4, 0xd2, 0xff, 0x62, 0xc6, 0x9d, 0x93,
-	0xd2, 0x1e, 0xb6, 0xcc, 0x6b, 0xff, 0xe4, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcc, 0xef, 0x0b,
-	0x54, 0x30, 0x0a, 0x00, 0x00,
+	0x13, 0xfe, 0x65, 0xeb, 0xb0, 0xdb, 0x8a, 0x13, 0x79, 0x1c, 0x27, 0x8a, 0x7e, 0x93, 0x04, 0x41,
+	0x55, 0x02, 0x01, 0xb9, 0xa2, 0x50, 0xc5, 0xa1, 0xa0, 0x52, 0xb1, 0x1d, 0x2a, 0x76, 0xc0, 0x56,
+	0x8d, 0x4d, 0x02, 0x57, 0x53, 0xa3, 0xdd, 0xb6, 0x34, 0x95, 0x3d, 0x31, 0x33, 0x32, 0x88, 0xe2,
+	0x19, 0x28, 0x9e, 0x80, 0xb7, 0xe0, 0x0d, 0x78, 0x03, 0x9e, 0x85, 0x7b, 0x6a, 0x0e, 0xbb, 0x8a,
+	0x6d, 0x25, 0x17, 0x5c, 0x69, 0xbb, 0xfb, 0x9b, 0xee, 0xe9, 0xfe, 0xba, 0x7b, 0x04, 0x9b, 0x51,
+	0x9e, 0xa6, 0x3c, 0x8b, 0xb7, 0xfd, 0xef, 0xa0, 0x90, 0xb9, 0xce, 0x49, 0xcb, 0x8b, 0xbd, 0x0d,
+	0x5e, 0x88, 0xed, 0x49, 0x9e, 0x72, 0x16, 0x73, 0xcd, 0x9d, 0xb5, 0x77, 0x67, 0x92, 0xe7, 0x93,
+	0x04, 0xb7, 0xad, 0x34, 0x9e, 0x9d, 0x6e, 0x6b, 0x91, 0xa2, 0xd2, 0x3c, 0x2d, 0x1c, 0xa0, 0xff,
+	0x23, 0x04, 0xc7, 0x98, 0x60, 0xa4, 0x73, 0x49, 0x08, 0xd4, 0x33, 0x9e, 0x62, 0xb7, 0x76, 0xb7,
+	0x76, 0x3f, 0xa4, 0xf6, 0x9b, 0x74, 0xa1, 0x75, 0x86, 0x52, 0x89, 0x3c, 0xeb, 0xae, 0x58, 0x75,
+	0x29, 0x92, 0x1b, 0xd0, 0xd4, 0x5c, 0x4e, 0x50, 0x77, 0x57, 0xad, 0xc1, 0x4b, 0xe4, 0x0e, 0xb4,
+	0xc7, 0x22, 0xe3, 0x72, 0xce, 0xa6, 0x5c, 0x4d, 0xbb, 0x75, 0x6b, 0x04, 0xa7, 0x7a, 0xc6, 0xd5,
+	0xb4, 0xff, 0x77, 0x0d, 0x82, 0xaf, 0x45, 0x82, 0xc7, 0x05, 0x46, 0x26, 0x66, 0xc1, 0xf5, 0xb4,
+	0x8c, 0x69, 0xbe, 0x8d, 0x4e, 0x89, 0x5f, 0xd0, 0x06, 0x5c, 0xa5, 0xf6, 0xdb, 0xe8, 0xac, 0x3b,
+	0x17, 0xcb, 0x7e, 0x93, 0xf7, 0x60, 0x4d, 0x28, 0x86, 0x3f, 0x63, 0x34, 0xd3, 0x7c, 0x9c, 0xa0,
+	0x8d, 0x15, 0xd0, 0x2b, 0x42, 0x3d, 0xad, 0x74, 0x26, 0x01, 0x35, 0x4f, 0x13, 0x91, 0xbd, 0xea,
+	0x36, 0x5c, 0x02, 0x5e, 0x24, 0xb7, 0x20, 0x30, 0x6e, 0xd8, 0x2b, 0x9c, 0x77, 0x9b, 0xce, 0x64,
+	0xe4, 0xe7, 0x38, 0x27, 0x0f, 0xa0, 0x3e, 0x4e, 0xf2, 0x71, 0xb7, 0x75, 0xb7, 0x76, 0xbf, 0x3d,
+	0xbc, 0x39, 0x88, 0xf1, 0x4c, 0xe7, 0x79, 0xa2, 0x98, 0xa9, 0xef, 0xc0, 0x5c, 0x7e, 0x27, 0xc9,
+	0xc7, 0xd4, 0x82, 0x0e, 0xea, 0x41, 0xd0, 0x09, 0xfb, 0x5b, 0xd0, 0x3c, 0x71, 0x05, 0x20, 0x50,
+	0xe7, 0x71, 0x2c, 0xcb, 0x94, 0xcc, 0x77, 0xff, 0x9f, 0x1a, 0x84, 0x3b, 0x33, 0x91, 0xc4, 0xfb,
+	0xd9, 0x69, 0x6e, 0xee, 0x14, 0x49, 0xe4, 0x3a, 0x97, 0x65, 0x51, 0xbd, 0x48, 0x7a, 0x10, 0x4c,
+	0x73, 0xa5, 0x2d, 0x0d, 0x2e, 0xd5, 0x4a, 0x26, 0x5b, 0x10, 0xc6, 0x42, 0x5a, 0xaa, 0xe6, 0xbe,
+	0xac, 0x0b, 0x05, 0xf9, 0x0c, 0xc2, 0x8a, 0x5b, 0x9b, 0x69, 0x7b, 0xd8, 0x1b, 0x38, 0xf6, 0x07,
+	0x25, 0xfb, 0x83, 0x93, 0x12, 0x41, 0x17, 0x60, 0xf2, 0x0e, 0x40, 0x94, 0xc6, 0x4c, 0xa1, 0x3c,
+	0x43, 0x69, 0x53, 0x0e, 0x69, 0x18, 0xa5, 0xf1, 0xb1, 0x55, 0x98, 0xb0, 0x26, 0xf7, 0x68, 0xca,
+	0x45, 0xd6, 0x0d, 0x9c, 0xb5, 0x52, 0x1c, 0xd4, 0x83, 0x5a, 0x67, 0xe5, 0xa0, 0x1e, 0x34, 0x3b,
+	0x2d, 0xda, 0x34, 0xad, 0x28, 0x34, 0x0d, 0x67, 0x85, 0xd2, 0x12, 0x79, 0xaa, 0xfa, 0xbf, 0x37,
+	0x60, 0x6d, 0x37, 0x8d, 0xf7, 0x50, 0x45, 0x52, 0x14, 0x26, 0xc3, 0x8f, 0x21, 0x50, 0xbe, 0xe1,
+	0x6c, 0x85, 0xda, 0xc3, 0xf5, 0x41, 0xd9, 0xd1, 0x65, 0x27, 0xd2, 0x0a, 0x42, 0x86, 0xd0, 0x50,
+	0xa8, 0x67, 0x85, 0x2d, 0x54, 0x7b, 0xb8, 0x55, 0x61, 0xcf, 0x79, 0x1d, 0x1c, 0x1b, 0x0c, 0x75,
+	0x50, 0x73, 0x26, 0x92, 0xb9, 0x52, 0xb6, 0x82, 0x6f, 0x3e, 0xb3, 0x6b, 0x30, 0xd4, 0x41, 0xc9,
+	0x73, 0xb8, 0x8a, 0xe9, 0x2c, 0xe1, 0x5a, 0xe4, 0x19, 0xcb, 0x0b, 0xad, 0x6c, 0x4b, 0xb4, 0x87,
+	0xef, 0xbf, 0xe1, 0xf0, 0xd3, 0x12, 0x7c, 0x54, 0x68, 0x45, 0xd7, 0xf0, 0x75, 0xb1, 0xf7, 0x67,
+	0x0d, 0x1a, 0xf6, 0x46, 0xe4, 0x23, 0x08, 0x4c, 0x6d, 0x4f, 0x45, 0x82, 0x97, 0xb2, 0x2d, 0x67,
+	0x80, 0xb6, 0xa2, 0x34, 0x36, 0x02, 0xb9, 0x09, 0xe6, 0x93, 0xc5, 0xa2, 0xec, 0x8b, 0x66, 0x94,
+	0xc6, 0x7b, 0x42, 0x92, 0x7b, 0xd0, 0x30, 0x2e, 0x4c, 0x46, 0xab, 0xcb, 0x7d, 0x38, 0x3b, 0xf9,
+	0x12, 0x42, 0x33, 0x42, 0x4c, 0xcf, 0x0b, 0x37, 0x0e, 0x57, 0x87, 0x77, 0xde, 0x90, 0xc1, 0x88,
+	0xeb, 0xe9, 0xc9, 0xbc, 0x40, 0x1a, 0x14, 0xfe, 0xab, 0xf7, 0x08, 0x1a, 0xb6, 0x28, 0xe4, 0x43,
+	0x58, 0x8f, 0x12, 0x9e, 0x4d, 0x58, 0x86, 0x18, 0x33, 0x3f, 0xe6, 0x35, 0x3b, 0x5d, 0xd7, 0xac,
+	0xe1, 0x10, 0x31, 0x76, 0xed, 0xde, 0x1b, 0xc1, 0xda, 0xb9, 0x62, 0x90, 0xc7, 0xb0, 0x25, 0x51,
+	0x15, 0x18, 0x69, 0x16, 0x25, 0x02, 0x33, 0xcd, 0x44, 0x16, 0x25, 0xb3, 0x18, 0x99, 0x09, 0xa4,
+	0xbc, 0x9f, 0x5b, 0x1e, 0xb3, 0x6b, 0x21, 0xfb, 0x0e, 0x61, 0xee, 0xa4, 0xfa, 0x9f, 0x43, 0x50,
+	0x5e, 0x8e, 0x6c, 0xc2, 0xfa, 0x77, 0x87, 0xcf, 0x0f, 0x8f, 0x5e, 0x1e, 0xb2, 0xd1, 0x93, 0x93,
+	0x67, 0xec, 0xe4, 0x87, 0xd1, 0xd3, 0xce, 0xff, 0x48, 0x08, 0x8d, 0xd1, 0xd1, 0xf1, 0xfe, 0xf7,
+	0x9d, 0x1a, 0x69, 0x43, 0xeb, 0xe5, 0xfe, 0xe1, 0xde, 0xd1, 0xcb, 0x63, 0xdb, 0x88, 0xf5, 0x4e,
+	0xe3, 0xa0, 0x1e, 0x34, 0x3a, 0x4d, 0x6a, 0x2b, 0x6f, 0xa8, 0xa4, 0xed, 0x82, 0x47, 0xaf, 0xf8,
+	0x04, 0x8d, 0xd4, 0xff, 0xab, 0x06, 0x84, 0x62, 0x9a, 0x6b, 0x34, 0x9b, 0x63, 0x94, 0x70, 0x7d,
+	0x9a, 0xcb, 0x94, 0xec, 0x01, 0x14, 0x32, 0x2f, 0x50, 0x6a, 0x81, 0xe6, 0x8e, 0xab, 0xe7, 0xc8,
+	0xbf, 0x7c, 0x60, 0x30, 0x72, 0xe8, 0x39, 0x7d, 0xed, 0x1c, 0x19, 0xc2, 0xa6, 0x1c, 0x23, 0x13,
+	0x99, 0xd2, 0x3c, 0x8b, 0x90, 0x8d, 0xb9, 0x42, 0x3b, 0xcc, 0x8e, 0xcf, 0x0d, 0x39, 0xc6, 0x7d,
+	0x6f, 0xdb, 0xf1, 0xa6, 0xde, 0x27, 0x10, 0x94, 0xbe, 0x96, 0xae, 0xe0, 0xeb, 0xd0, 0x38, 0xe3,
+	0xc9, 0xac, 0xf4, 0xe1, 0x84, 0xfe, 0x1f, 0x2b, 0xd0, 0xdc, 0xcd, 0xb3, 0x53, 0x31, 0x21, 0xf7,
+	0xaa, 0x4d, 0xec, 0x5a, 0xec, 0x5a, 0x75, 0x6d, 0x47, 0x51, 0xb5, 0x9a, 0x1f, 0x02, 0x8c, 0xcd,
+	0x12, 0x62, 0x22, 0x3b, 0xcd, 0xfd, 0x74, 0x90, 0x0a, 0x5c, 0xed, 0x27, 0x1a, 0x8e, 0xab, 0x55,
+	0xf5, 0x15, 0x5c, 0xb5, 0x2d, 0x59, 0xf5, 0x8d, 0xed, 0xaa, 0xf6, 0xf0, 0xc6, 0xf2, 0xae, 0xa2,
+	0x6b, 0xd1, 0xb9, 0x69, 0xff, 0x06, 0x36, 0x64, 0x55, 0x3a, 0x56, 0xf8, 0xda, 0xf9, 0xfd, 0xf4,
+	0xff, 0xb7, 0x94, 0x97, 0x12, 0x79, 0x99, 0xa3, 0xdb, 0x00, 0xb1, 0x48, 0x31, 0x33, 0xef, 0x8f,
+	0x19, 0xd0, 0x55, 0xf3, 0xb2, 0x2c, 0x34, 0x07, 0xf5, 0x60, 0xa5, 0xb3, 0x4a, 0x1b, 0x22, 0xe5,
+	0x13, 0xec, 0xff, 0x0a, 0x41, 0x75, 0xf0, 0x8b, 0x25, 0xe4, 0xf6, 0xaa, 0xe8, 0x6f, 0xa5, 0xf4,
+	0x3f, 0xd2, 0xf3, 0xdb, 0x2a, 0xac, 0xd1, 0x59, 0x66, 0xb6, 0xac, 0x67, 0x69, 0xd9, 0xd9, 0x77,
+	0xe1, 0x8a, 0x59, 0xbb, 0x22, 0x42, 0x66, 0x9f, 0x0c, 0xe7, 0xa2, 0xed, 0x75, 0x4f, 0xe2, 0x58,
+	0x92, 0x17, 0x70, 0xb3, 0x2c, 0x1b, 0x93, 0xce, 0x21, 0x8b, 0xac, 0x47, 0xbf, 0xa1, 0x6e, 0x5f,
+	0xca, 0xe3, 0x5c, 0x5c, 0xba, 0x59, 0x2c, 0x53, 0x9b, 0x3d, 0x5c, 0xd1, 0x11, 0x5c, 0xd8, 0x4c,
+	0x95, 0xa3, 0x0a, 0x42, 0x1e, 0xc0, 0x3a, 0x4f, 0x92, 0xfc, 0x27, 0x8c, 0x59, 0x21, 0xd1, 0xf4,
+	0x87, 0x76, 0xdb, 0x28, 0xa4, 0x1d, 0x6f, 0x18, 0x95, 0x7a, 0xf2, 0x10, 0xae, 0xc7, 0x42, 0x5d,
+	0xc6, 0xd7, 0x2d, 0x7e, 0x63, 0x61, 0x5b, 0x1c, 0xd9, 0x81, 0xd7, 0xd4, 0xcc, 0x5f, 0x44, 0x75,
+	0x1b, 0x17, 0xf6, 0x5d, 0xf5, 0x42, 0x90, 0x05, 0x7a, 0xd7, 0x83, 0x0f, 0xea, 0x41, 0xab, 0x13,
+	0xd0, 0xe5, 0x03, 0xd8, 0xff, 0x14, 0x36, 0x97, 0xd6, 0xe7, 0x42, 0x53, 0xd5, 0x2e, 0x36, 0x55,
+	0xff, 0x31, 0x84, 0x0e, 0xf9, 0x2d, 0x37, 0x4f, 0x4b, 0xe0, 0x49, 0x28, 0xdb, 0x68, 0x31, 0x08,
+	0xe7, 0xcb, 0x5e, 0xe1, 0xfa, 0x2f, 0x00, 0xbc, 0x0e, 0x95, 0x7d, 0x6d, 0xfd, 0x3f, 0x28, 0x26,
+	0x62, 0x4f, 0x78, 0xe8, 0x35, 0xfb, 0x31, 0xf9, 0x00, 0x5a, 0x8e, 0xdd, 0xd2, 0xff, 0x62, 0x98,
+	0xbd, 0x93, 0xd2, 0x3e, 0x6e, 0xda, 0x67, 0xfd, 0xd1, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x39,
+	0xb9, 0x5b, 0xc4, 0x19, 0x0a, 0x00, 0x00,
 }
diff --git a/proto/command/command.proto b/proto/command/command.proto
index e957410..eb849e8 100644
--- a/proto/command/command.proto
+++ b/proto/command/command.proto
@@ -213,8 +213,8 @@
   // the dimentions, this runtime config will be selected.
   PlatformRuntimeConfig platform_runtime_config = 6;
 
-  // Basename of RBE instance to use. e.g. "default_instance" or "windows".
-  string rbe_instance_basename = 7;
+  reserved 7;
+  reserved "rbe_instance_basename";
 
   // Platform is a set of requirements, such as haredware, operting system
   // for RBE backend.
diff --git a/proto/copy_google_protobuf.sh b/proto/copy_google_protobuf.sh
index 6034302..3aced9b 100755
--- a/proto/copy_google_protobuf.sh
+++ b/proto/copy_google_protobuf.sh
@@ -3,14 +3,3 @@
 protobufdir="$(go list -m -f '{{.Dir}}' github.com/golang/protobuf)"
 cp "${protobufdir}/ptypes/timestamp/timestamp.proto" \
   ./google/protobuf/timestamp.proto
-
-# for remote-apis v2
-
-cp "${protobufdir}/ptypes/duration/duration.proto" \
-  ./google/protobuf/duration.proto
-cp "${protobufdir}/ptypes/any/any.proto" \
-  ./google/protobuf/any.proto
-cp "${protobufdir}/ptypes/empty/empty.proto" \
-  ./google/protobuf/empty.proto
-cp "${protobufdir}/protoc-gen-go/descriptor/descriptor.proto" \
-  ./google/protobuf/descriptor.proto
diff --git a/proto/google/api/annotations.proto b/proto/google/api/annotations.proto
deleted file mode 100644
index 85c361b..0000000
--- a/proto/google/api/annotations.proto
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2015, Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-syntax = "proto3";
-
-package google.api;
-
-import "google/api/http.proto";
-import "google/protobuf/descriptor.proto";
-
-option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations";
-option java_multiple_files = true;
-option java_outer_classname = "AnnotationsProto";
-option java_package = "com.google.api";
-option objc_class_prefix = "GAPI";
-
-extend google.protobuf.MethodOptions {
-  // See `HttpRule`.
-  HttpRule http = 72295728;
-}
diff --git a/proto/google/api/http.proto b/proto/google/api/http.proto
deleted file mode 100644
index 78d515d..0000000
--- a/proto/google/api/http.proto
+++ /dev/null
@@ -1,313 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-syntax = "proto3";
-
-package google.api;
-
-option cc_enable_arenas = true;
-option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations";
-option java_multiple_files = true;
-option java_outer_classname = "HttpProto";
-option java_package = "com.google.api";
-option objc_class_prefix = "GAPI";
-
-
-// Defines the HTTP configuration for an API service. It contains a list of
-// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method
-// to one or more HTTP REST API methods.
-message Http {
-  // A list of HTTP configuration rules that apply to individual API methods.
-  //
-  // **NOTE:** All service configuration rules follow "last one wins" order.
-  repeated HttpRule rules = 1;
-
-  // When set to true, URL path parmeters will be fully URI-decoded except in
-  // cases of single segment matches in reserved expansion, where "%2F" will be
-  // left encoded.
-  //
-  // The default behavior is to not decode RFC 6570 reserved characters in multi
-  // segment matches.
-  bool fully_decode_reserved_expansion = 2;
-}
-
-// `HttpRule` defines the mapping of an RPC method to one or more HTTP
-// REST API methods. The mapping specifies how different portions of the RPC
-// request message are mapped to URL path, URL query parameters, and
-// HTTP request body. The mapping is typically specified as an
-// `google.api.http` annotation on the RPC method,
-// see "google/api/annotations.proto" for details.
-//
-// The mapping consists of a field specifying the path template and
-// method kind.  The path template can refer to fields in the request
-// message, as in the example below which describes a REST GET
-// operation on a resource collection of messages:
-//
-//
-//     service Messaging {
-//       rpc GetMessage(GetMessageRequest) returns (Message) {
-//         option (google.api.http).get = "/v1/messages/{message_id}/{sub.subfield}";
-//       }
-//     }
-//     message GetMessageRequest {
-//       message SubMessage {
-//         string subfield = 1;
-//       }
-//       string message_id = 1; // mapped to the URL
-//       SubMessage sub = 2;    // `sub.subfield` is url-mapped
-//     }
-//     message Message {
-//       string text = 1; // content of the resource
-//     }
-//
-// The same http annotation can alternatively be expressed inside the
-// `GRPC API Configuration` YAML file.
-//
-//     http:
-//       rules:
-//         - selector: <proto_package_name>.Messaging.GetMessage
-//           get: /v1/messages/{message_id}/{sub.subfield}
-//
-// This definition enables an automatic, bidrectional mapping of HTTP
-// JSON to RPC. Example:
-//
-// HTTP | RPC
-// -----|-----
-// `GET /v1/messages/123456/foo`  | `GetMessage(message_id: "123456" sub: SubMessage(subfield: "foo"))`
-//
-// In general, not only fields but also field paths can be referenced
-// from a path pattern. Fields mapped to the path pattern cannot be
-// repeated and must have a primitive (non-message) type.
-//
-// Any fields in the request message which are not bound by the path
-// pattern automatically become (optional) HTTP query
-// parameters. Assume the following definition of the request message:
-//
-//
-//     service Messaging {
-//       rpc GetMessage(GetMessageRequest) returns (Message) {
-//         option (google.api.http).get = "/v1/messages/{message_id}";
-//       }
-//     }
-//     message GetMessageRequest {
-//       message SubMessage {
-//         string subfield = 1;
-//       }
-//       string message_id = 1; // mapped to the URL
-//       int64 revision = 2;    // becomes a parameter
-//       SubMessage sub = 3;    // `sub.subfield` becomes a parameter
-//     }
-//
-//
-// This enables a HTTP JSON to RPC mapping as below:
-//
-// HTTP | RPC
-// -----|-----
-// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: "foo"))`
-//
-// Note that fields which are mapped to HTTP parameters must have a
-// primitive type or a repeated primitive type. Message types are not
-// allowed. In the case of a repeated type, the parameter can be
-// repeated in the URL, as in `...?param=A&param=B`.
-//
-// For HTTP method kinds which allow a request body, the `body` field
-// specifies the mapping. Consider a REST update method on the
-// message resource collection:
-//
-//
-//     service Messaging {
-//       rpc UpdateMessage(UpdateMessageRequest) returns (Message) {
-//         option (google.api.http) = {
-//           put: "/v1/messages/{message_id}"
-//           body: "message"
-//         };
-//       }
-//     }
-//     message UpdateMessageRequest {
-//       string message_id = 1; // mapped to the URL
-//       Message message = 2;   // mapped to the body
-//     }
-//
-//
-// The following HTTP JSON to RPC mapping is enabled, where the
-// representation of the JSON in the request body is determined by
-// protos JSON encoding:
-//
-// HTTP | RPC
-// -----|-----
-// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" message { text: "Hi!" })`
-//
-// The special name `*` can be used in the body mapping to define that
-// every field not bound by the path template should be mapped to the
-// request body.  This enables the following alternative definition of
-// the update method:
-//
-//     service Messaging {
-//       rpc UpdateMessage(Message) returns (Message) {
-//         option (google.api.http) = {
-//           put: "/v1/messages/{message_id}"
-//           body: "*"
-//         };
-//       }
-//     }
-//     message Message {
-//       string message_id = 1;
-//       string text = 2;
-//     }
-//
-//
-// The following HTTP JSON to RPC mapping is enabled:
-//
-// HTTP | RPC
-// -----|-----
-// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" text: "Hi!")`
-//
-// Note that when using `*` in the body mapping, it is not possible to
-// have HTTP parameters, as all fields not bound by the path end in
-// the body. This makes this option more rarely used in practice of
-// defining REST APIs. The common usage of `*` is in custom methods
-// which don't use the URL at all for transferring data.
-//
-// It is possible to define multiple HTTP methods for one RPC by using
-// the `additional_bindings` option. Example:
-//
-//     service Messaging {
-//       rpc GetMessage(GetMessageRequest) returns (Message) {
-//         option (google.api.http) = {
-//           get: "/v1/messages/{message_id}"
-//           additional_bindings {
-//             get: "/v1/users/{user_id}/messages/{message_id}"
-//           }
-//         };
-//       }
-//     }
-//     message GetMessageRequest {
-//       string message_id = 1;
-//       string user_id = 2;
-//     }
-//
-//
-// This enables the following two alternative HTTP JSON to RPC
-// mappings:
-//
-// HTTP | RPC
-// -----|-----
-// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")`
-// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: "123456")`
-//
-// # Rules for HTTP mapping
-//
-// The rules for mapping HTTP path, query parameters, and body fields
-// to the request message are as follows:
-//
-// 1. The `body` field specifies either `*` or a field path, or is
-//    omitted. If omitted, it indicates there is no HTTP request body.
-// 2. Leaf fields (recursive expansion of nested messages in the
-//    request) can be classified into three types:
-//     (a) Matched in the URL template.
-//     (b) Covered by body (if body is `*`, everything except (a) fields;
-//         else everything under the body field)
-//     (c) All other fields.
-// 3. URL query parameters found in the HTTP request are mapped to (c) fields.
-// 4. Any body sent with an HTTP request can contain only (b) fields.
-//
-// The syntax of the path template is as follows:
-//
-//     Template = "/" Segments [ Verb ] ;
-//     Segments = Segment { "/" Segment } ;
-//     Segment  = "*" | "**" | LITERAL | Variable ;
-//     Variable = "{" FieldPath [ "=" Segments ] "}" ;
-//     FieldPath = IDENT { "." IDENT } ;
-//     Verb     = ":" LITERAL ;
-//
-// The syntax `*` matches a single path segment. The syntax `**` matches zero
-// or more path segments, which must be the last part of the path except the
-// `Verb`. The syntax `LITERAL` matches literal text in the path.
-//
-// The syntax `Variable` matches part of the URL path as specified by its
-// template. A variable template must not contain other variables. If a variable
-// matches a single path segment, its template may be omitted, e.g. `{var}`
-// is equivalent to `{var=*}`.
-//
-// If a variable contains exactly one path segment, such as `"{var}"` or
-// `"{var=*}"`, when such a variable is expanded into a URL path, all characters
-// except `[-_.~0-9a-zA-Z]` are percent-encoded. Such variables show up in the
-// Discovery Document as `{var}`.
-//
-// If a variable contains one or more path segments, such as `"{var=foo/*}"`
-// or `"{var=**}"`, when such a variable is expanded into a URL path, all
-// characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. Such variables
-// show up in the Discovery Document as `{+var}`.
-//
-// NOTE: While the single segment variable matches the semantics of
-// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2
-// Simple String Expansion, the multi segment variable **does not** match
-// RFC 6570 Reserved Expansion. The reason is that the Reserved Expansion
-// does not expand special characters like `?` and `#`, which would lead
-// to invalid URLs.
-//
-// NOTE: the field paths in variables and in the `body` must not refer to
-// repeated fields or map fields.
-message HttpRule {
-  // Selects methods to which this rule applies.
-  //
-  // Refer to [selector][google.api.DocumentationRule.selector] for syntax details.
-  string selector = 1;
-
-  // Determines the URL pattern is matched by this rules. This pattern can be
-  // used with any of the {get|put|post|delete|patch} methods. A custom method
-  // can be defined using the 'custom' field.
-  oneof pattern {
-    // Used for listing and getting information about resources.
-    string get = 2;
-
-    // Used for updating a resource.
-    string put = 3;
-
-    // Used for creating a resource.
-    string post = 4;
-
-    // Used for deleting a resource.
-    string delete = 5;
-
-    // Used for updating a resource.
-    string patch = 6;
-
-    // The custom pattern is used for specifying an HTTP method that is not
-    // included in the `pattern` field, such as HEAD, or "*" to leave the
-    // HTTP method unspecified for this rule. The wild-card rule is useful
-    // for services that provide content to Web (HTML) clients.
-    CustomHttpPattern custom = 8;
-  }
-
-  // The name of the request field whose value is mapped to the HTTP body, or
-  // `*` for mapping all fields not captured by the path pattern to the HTTP
-  // body. NOTE: the referred field must not be a repeated field and must be
-  // present at the top-level of request message type.
-  string body = 7;
-
-  // Additional HTTP bindings for the selector. Nested bindings must
-  // not contain an `additional_bindings` field themselves (that is,
-  // the nesting may only be one level deep).
-  repeated HttpRule additional_bindings = 11;
-}
-
-// A custom pattern is used for defining custom HTTP verb.
-message CustomHttpPattern {
-  // The name of this custom HTTP verb.
-  string kind = 1;
-
-  // The path matched by this custom verb.
-  string path = 2;
-}
diff --git a/proto/google/longrunning/operations.proto b/proto/google/longrunning/operations.proto
deleted file mode 100644
index 76fef29..0000000
--- a/proto/google/longrunning/operations.proto
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2016 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-syntax = "proto3";
-
-package google.longrunning;
-
-import "google/api/annotations.proto";
-import "google/protobuf/any.proto";
-import "google/protobuf/empty.proto";
-import "google/rpc/status.proto";
-
-option csharp_namespace = "Google.LongRunning";
-option go_package = "google.golang.org/genproto/googleapis/longrunning;longrunning";
-option java_multiple_files = true;
-option java_outer_classname = "OperationsProto";
-option java_package = "com.google.longrunning";
-option php_namespace = "Google\\LongRunning";
-
-
-// Manages long-running operations with an API service.
-//
-// When an API method normally takes long time to complete, it can be designed
-// to return [Operation][google.longrunning.Operation] to the client, and the client can use this
-// interface to receive the real response asynchronously by polling the
-// operation resource, or pass the operation resource to another API (such as
-// Google Cloud Pub/Sub API) to receive the response.  Any API service that
-// returns long-running operations should implement the `Operations` interface
-// so developers can have a consistent client experience.
-service Operations {
-  // Lists operations that match the specified filter in the request. If the
-  // server doesn't support this method, it returns `UNIMPLEMENTED`.
-  //
-  // NOTE: the `name` binding below allows API services to override the binding
-  // to use different resource name schemes, such as `users/*/operations`.
-  rpc ListOperations(ListOperationsRequest) returns (ListOperationsResponse) {
-    option (google.api.http) = { get: "/v1/{name=operations}" };
-  }
-
-  // Gets the latest state of a long-running operation.  Clients can use this
-  // method to poll the operation result at intervals as recommended by the API
-  // service.
-  rpc GetOperation(GetOperationRequest) returns (Operation) {
-    option (google.api.http) = { get: "/v1/{name=operations/**}" };
-  }
-
-  // Deletes a long-running operation. This method indicates that the client is
-  // no longer interested in the operation result. It does not cancel the
-  // operation. If the server doesn't support this method, it returns
-  // `google.rpc.Code.UNIMPLEMENTED`.
-  rpc DeleteOperation(DeleteOperationRequest) returns (google.protobuf.Empty) {
-    option (google.api.http) = { delete: "/v1/{name=operations/**}" };
-  }
-
-  // Starts asynchronous cancellation on a long-running operation.  The server
-  // makes a best effort to cancel the operation, but success is not
-  // guaranteed.  If the server doesn't support this method, it returns
-  // `google.rpc.Code.UNIMPLEMENTED`.  Clients can use
-  // [Operations.GetOperation][google.longrunning.Operations.GetOperation] or
-  // other methods to check whether the cancellation succeeded or whether the
-  // operation completed despite cancellation. On successful cancellation,
-  // the operation is not deleted; instead, it becomes an operation with
-  // an [Operation.error][google.longrunning.Operation.error] value with a [google.rpc.Status.code][google.rpc.Status.code] of 1,
-  // corresponding to `Code.CANCELLED`.
-  rpc CancelOperation(CancelOperationRequest) returns (google.protobuf.Empty) {
-    option (google.api.http) = { post: "/v1/{name=operations/**}:cancel" body: "*" };
-  }
-}
-
-// This resource represents a long-running operation that is the result of a
-// network API call.
-message Operation {
-  // The server-assigned name, which is only unique within the same service that
-  // originally returns it. If you use the default HTTP mapping, the
-  // `name` should have the format of `operations/some/unique/name`.
-  string name = 1;
-
-  // Service-specific metadata associated with the operation.  It typically
-  // contains progress information and common metadata such as create time.
-  // Some services might not provide such metadata.  Any method that returns a
-  // long-running operation should document the metadata type, if any.
-  google.protobuf.Any metadata = 2;
-
-  // If the value is `false`, it means the operation is still in progress.
-  // If true, the operation is completed, and either `error` or `response` is
-  // available.
-  bool done = 3;
-
-  // The operation result, which can be either an `error` or a valid `response`.
-  // If `done` == `false`, neither `error` nor `response` is set.
-  // If `done` == `true`, exactly one of `error` or `response` is set.
-  oneof result {
-    // The error result of the operation in case of failure or cancellation.
-    google.rpc.Status error = 4;
-
-    // The normal response of the operation in case of success.  If the original
-    // method returns no data on success, such as `Delete`, the response is
-    // `google.protobuf.Empty`.  If the original method is standard
-    // `Get`/`Create`/`Update`, the response should be the resource.  For other
-    // methods, the response should have the type `XxxResponse`, where `Xxx`
-    // is the original method name.  For example, if the original method name
-    // is `TakeSnapshot()`, the inferred response type is
-    // `TakeSnapshotResponse`.
-    google.protobuf.Any response = 5;
-  }
-}
-
-// The request message for [Operations.GetOperation][google.longrunning.Operations.GetOperation].
-message GetOperationRequest {
-  // The name of the operation resource.
-  string name = 1;
-}
-
-// The request message for [Operations.ListOperations][google.longrunning.Operations.ListOperations].
-message ListOperationsRequest {
-  // The name of the operation collection.
-  string name = 4;
-
-  // The standard list filter.
-  string filter = 1;
-
-  // The standard list page size.
-  int32 page_size = 2;
-
-  // The standard list page token.
-  string page_token = 3;
-}
-
-// The response message for [Operations.ListOperations][google.longrunning.Operations.ListOperations].
-message ListOperationsResponse {
-  // A list of operations that matches the specified filter in the request.
-  repeated Operation operations = 1;
-
-  // The standard List next-page token.
-  string next_page_token = 2;
-}
-
-// The request message for [Operations.CancelOperation][google.longrunning.Operations.CancelOperation].
-message CancelOperationRequest {
-  // The name of the operation resource to be cancelled.
-  string name = 1;
-}
-
-// The request message for [Operations.DeleteOperation][google.longrunning.Operations.DeleteOperation].
-message DeleteOperationRequest {
-  // The name of the operation resource to be deleted.
-  string name = 1;
-}
-
diff --git a/proto/google/protobuf/any.proto b/proto/google/protobuf/any.proto
deleted file mode 100644
index 4932942..0000000
--- a/proto/google/protobuf/any.proto
+++ /dev/null
@@ -1,154 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-
-package google.protobuf;
-
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option go_package = "github.com/golang/protobuf/ptypes/any";
-option java_package = "com.google.protobuf";
-option java_outer_classname = "AnyProto";
-option java_multiple_files = true;
-option objc_class_prefix = "GPB";
-
-// `Any` contains an arbitrary serialized protocol buffer message along with a
-// URL that describes the type of the serialized message.
-//
-// Protobuf library provides support to pack/unpack Any values in the form
-// of utility functions or additional generated methods of the Any type.
-//
-// Example 1: Pack and unpack a message in C++.
-//
-//     Foo foo = ...;
-//     Any any;
-//     any.PackFrom(foo);
-//     ...
-//     if (any.UnpackTo(&foo)) {
-//       ...
-//     }
-//
-// Example 2: Pack and unpack a message in Java.
-//
-//     Foo foo = ...;
-//     Any any = Any.pack(foo);
-//     ...
-//     if (any.is(Foo.class)) {
-//       foo = any.unpack(Foo.class);
-//     }
-//
-//  Example 3: Pack and unpack a message in Python.
-//
-//     foo = Foo(...)
-//     any = Any()
-//     any.Pack(foo)
-//     ...
-//     if any.Is(Foo.DESCRIPTOR):
-//       any.Unpack(foo)
-//       ...
-//
-//  Example 4: Pack and unpack a message in Go
-//
-//      foo := &pb.Foo{...}
-//      any, err := ptypes.MarshalAny(foo)
-//      ...
-//      foo := &pb.Foo{}
-//      if err := ptypes.UnmarshalAny(any, foo); err != nil {
-//        ...
-//      }
-//
-// The pack methods provided by protobuf library will by default use
-// 'type.googleapis.com/full.type.name' as the type URL and the unpack
-// methods only use the fully qualified type name after the last '/'
-// in the type URL, for example "foo.bar.com/x/y.z" will yield type
-// name "y.z".
-//
-//
-// JSON
-// ====
-// The JSON representation of an `Any` value uses the regular
-// representation of the deserialized, embedded message, with an
-// additional field `@type` which contains the type URL. Example:
-//
-//     package google.profile;
-//     message Person {
-//       string first_name = 1;
-//       string last_name = 2;
-//     }
-//
-//     {
-//       "@type": "type.googleapis.com/google.profile.Person",
-//       "firstName": <string>,
-//       "lastName": <string>
-//     }
-//
-// If the embedded message type is well-known and has a custom JSON
-// representation, that representation will be embedded adding a field
-// `value` which holds the custom JSON in addition to the `@type`
-// field. Example (for message [google.protobuf.Duration][]):
-//
-//     {
-//       "@type": "type.googleapis.com/google.protobuf.Duration",
-//       "value": "1.212s"
-//     }
-//
-message Any {
-  // A URL/resource name that uniquely identifies the type of the serialized
-  // protocol buffer message. The last segment of the URL's path must represent
-  // the fully qualified name of the type (as in
-  // `path/google.protobuf.Duration`). The name should be in a canonical form
-  // (e.g., leading "." is not accepted).
-  //
-  // In practice, teams usually precompile into the binary all types that they
-  // expect it to use in the context of Any. However, for URLs which use the
-  // scheme `http`, `https`, or no scheme, one can optionally set up a type
-  // server that maps type URLs to message definitions as follows:
-  //
-  // * If no scheme is provided, `https` is assumed.
-  // * An HTTP GET on the URL must yield a [google.protobuf.Type][]
-  //   value in binary format, or produce an error.
-  // * Applications are allowed to cache lookup results based on the
-  //   URL, or have them precompiled into a binary to avoid any
-  //   lookup. Therefore, binary compatibility needs to be preserved
-  //   on changes to types. (Use versioned type names to manage
-  //   breaking changes.)
-  //
-  // Note: this functionality is not currently available in the official
-  // protobuf release, and it is not used for type URLs beginning with
-  // type.googleapis.com.
-  //
-  // Schemes other than `http`, `https` (or the empty scheme) might be
-  // used with implementation specific semantics.
-  //
-  string type_url = 1;
-
-  // Must be a valid serialized protocol buffer of the above specified type.
-  bytes value = 2;
-}
diff --git a/proto/google/protobuf/descriptor.proto b/proto/google/protobuf/descriptor.proto
deleted file mode 100644
index ed08fcb..0000000
--- a/proto/google/protobuf/descriptor.proto
+++ /dev/null
@@ -1,883 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: kenton@google.com (Kenton Varda)
-//  Based on original Protocol Buffers design by
-//  Sanjay Ghemawat, Jeff Dean, and others.
-//
-// The messages in this file describe the definitions found in .proto files.
-// A valid .proto file can be translated directly to a FileDescriptorProto
-// without any other information (e.g. without reading its imports).
-
-
-syntax = "proto2";
-
-package google.protobuf;
-option go_package = "github.com/golang/protobuf/protoc-gen-go/descriptor;descriptor";
-option java_package = "com.google.protobuf";
-option java_outer_classname = "DescriptorProtos";
-option csharp_namespace = "Google.Protobuf.Reflection";
-option objc_class_prefix = "GPB";
-option cc_enable_arenas = true;
-
-// descriptor.proto must be optimized for speed because reflection-based
-// algorithms don't work during bootstrapping.
-option optimize_for = SPEED;
-
-// The protocol compiler can output a FileDescriptorSet containing the .proto
-// files it parses.
-message FileDescriptorSet {
-  repeated FileDescriptorProto file = 1;
-}
-
-// Describes a complete .proto file.
-message FileDescriptorProto {
-  optional string name = 1;       // file name, relative to root of source tree
-  optional string package = 2;    // e.g. "foo", "foo.bar", etc.
-
-  // Names of files imported by this file.
-  repeated string dependency = 3;
-  // Indexes of the public imported files in the dependency list above.
-  repeated int32 public_dependency = 10;
-  // Indexes of the weak imported files in the dependency list.
-  // For Google-internal migration only. Do not use.
-  repeated int32 weak_dependency = 11;
-
-  // All top-level definitions in this file.
-  repeated DescriptorProto message_type = 4;
-  repeated EnumDescriptorProto enum_type = 5;
-  repeated ServiceDescriptorProto service = 6;
-  repeated FieldDescriptorProto extension = 7;
-
-  optional FileOptions options = 8;
-
-  // This field contains optional information about the original source code.
-  // You may safely remove this entire field without harming runtime
-  // functionality of the descriptors -- the information is needed only by
-  // development tools.
-  optional SourceCodeInfo source_code_info = 9;
-
-  // The syntax of the proto file.
-  // The supported values are "proto2" and "proto3".
-  optional string syntax = 12;
-}
-
-// Describes a message type.
-message DescriptorProto {
-  optional string name = 1;
-
-  repeated FieldDescriptorProto field = 2;
-  repeated FieldDescriptorProto extension = 6;
-
-  repeated DescriptorProto nested_type = 3;
-  repeated EnumDescriptorProto enum_type = 4;
-
-  message ExtensionRange {
-    optional int32 start = 1;
-    optional int32 end = 2;
-
-    optional ExtensionRangeOptions options = 3;
-  }
-  repeated ExtensionRange extension_range = 5;
-
-  repeated OneofDescriptorProto oneof_decl = 8;
-
-  optional MessageOptions options = 7;
-
-  // Range of reserved tag numbers. Reserved tag numbers may not be used by
-  // fields or extension ranges in the same message. Reserved ranges may
-  // not overlap.
-  message ReservedRange {
-    optional int32 start = 1; // Inclusive.
-    optional int32 end = 2;   // Exclusive.
-  }
-  repeated ReservedRange reserved_range = 9;
-  // Reserved field names, which may not be used by fields in the same message.
-  // A given name may only be reserved once.
-  repeated string reserved_name = 10;
-}
-
-message ExtensionRangeOptions {
-  // The parser stores options it doesn't recognize here. See above.
-  repeated UninterpretedOption uninterpreted_option = 999;
-
-  // Clients can define custom options in extensions of this message. See above.
-  extensions 1000 to max;
-}
-
-// Describes a field within a message.
-message FieldDescriptorProto {
-  enum Type {
-    // 0 is reserved for errors.
-    // Order is weird for historical reasons.
-    TYPE_DOUBLE         = 1;
-    TYPE_FLOAT          = 2;
-    // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT64 if
-    // negative values are likely.
-    TYPE_INT64          = 3;
-    TYPE_UINT64         = 4;
-    // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT32 if
-    // negative values are likely.
-    TYPE_INT32          = 5;
-    TYPE_FIXED64        = 6;
-    TYPE_FIXED32        = 7;
-    TYPE_BOOL           = 8;
-    TYPE_STRING         = 9;
-    // Tag-delimited aggregate.
-    // Group type is deprecated and not supported in proto3. However, Proto3
-    // implementations should still be able to parse the group wire format and
-    // treat group fields as unknown fields.
-    TYPE_GROUP          = 10;
-    TYPE_MESSAGE        = 11;  // Length-delimited aggregate.
-
-    // New in version 2.
-    TYPE_BYTES          = 12;
-    TYPE_UINT32         = 13;
-    TYPE_ENUM           = 14;
-    TYPE_SFIXED32       = 15;
-    TYPE_SFIXED64       = 16;
-    TYPE_SINT32         = 17;  // Uses ZigZag encoding.
-    TYPE_SINT64         = 18;  // Uses ZigZag encoding.
-  };
-
-  enum Label {
-    // 0 is reserved for errors
-    LABEL_OPTIONAL      = 1;
-    LABEL_REQUIRED      = 2;
-    LABEL_REPEATED      = 3;
-  };
-
-  optional string name = 1;
-  optional int32 number = 3;
-  optional Label label = 4;
-
-  // If type_name is set, this need not be set.  If both this and type_name
-  // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
-  optional Type type = 5;
-
-  // For message and enum types, this is the name of the type.  If the name
-  // starts with a '.', it is fully-qualified.  Otherwise, C++-like scoping
-  // rules are used to find the type (i.e. first the nested types within this
-  // message are searched, then within the parent, on up to the root
-  // namespace).
-  optional string type_name = 6;
-
-  // For extensions, this is the name of the type being extended.  It is
-  // resolved in the same manner as type_name.
-  optional string extendee = 2;
-
-  // For numeric types, contains the original text representation of the value.
-  // For booleans, "true" or "false".
-  // For strings, contains the default text contents (not escaped in any way).
-  // For bytes, contains the C escaped value.  All bytes >= 128 are escaped.
-  // TODO(kenton):  Base-64 encode?
-  optional string default_value = 7;
-
-  // If set, gives the index of a oneof in the containing type's oneof_decl
-  // list.  This field is a member of that oneof.
-  optional int32 oneof_index = 9;
-
-  // JSON name of this field. The value is set by protocol compiler. If the
-  // user has set a "json_name" option on this field, that option's value
-  // will be used. Otherwise, it's deduced from the field's name by converting
-  // it to camelCase.
-  optional string json_name = 10;
-
-  optional FieldOptions options = 8;
-}
-
-// Describes a oneof.
-message OneofDescriptorProto {
-  optional string name = 1;
-  optional OneofOptions options = 2;
-}
-
-// Describes an enum type.
-message EnumDescriptorProto {
-  optional string name = 1;
-
-  repeated EnumValueDescriptorProto value = 2;
-
-  optional EnumOptions options = 3;
-
-  // Range of reserved numeric values. Reserved values may not be used by
-  // entries in the same enum. Reserved ranges may not overlap.
-  //
-  // Note that this is distinct from DescriptorProto.ReservedRange in that it
-  // is inclusive such that it can appropriately represent the entire int32
-  // domain.
-  message EnumReservedRange {
-    optional int32 start = 1; // Inclusive.
-    optional int32 end = 2;   // Inclusive.
-  }
-
-  // Range of reserved numeric values. Reserved numeric values may not be used
-  // by enum values in the same enum declaration. Reserved ranges may not
-  // overlap.
-  repeated EnumReservedRange reserved_range = 4;
-
-  // Reserved enum value names, which may not be reused. A given name may only
-  // be reserved once.
-  repeated string reserved_name = 5;
-}
-
-// Describes a value within an enum.
-message EnumValueDescriptorProto {
-  optional string name = 1;
-  optional int32 number = 2;
-
-  optional EnumValueOptions options = 3;
-}
-
-// Describes a service.
-message ServiceDescriptorProto {
-  optional string name = 1;
-  repeated MethodDescriptorProto method = 2;
-
-  optional ServiceOptions options = 3;
-}
-
-// Describes a method of a service.
-message MethodDescriptorProto {
-  optional string name = 1;
-
-  // Input and output type names.  These are resolved in the same way as
-  // FieldDescriptorProto.type_name, but must refer to a message type.
-  optional string input_type = 2;
-  optional string output_type = 3;
-
-  optional MethodOptions options = 4;
-
-  // Identifies if client streams multiple client messages
-  optional bool client_streaming = 5 [default=false];
-  // Identifies if server streams multiple server messages
-  optional bool server_streaming = 6 [default=false];
-}
-
-
-// ===================================================================
-// Options
-
-// Each of the definitions above may have "options" attached.  These are
-// just annotations which may cause code to be generated slightly differently
-// or may contain hints for code that manipulates protocol messages.
-//
-// Clients may define custom options as extensions of the *Options messages.
-// These extensions may not yet be known at parsing time, so the parser cannot
-// store the values in them.  Instead it stores them in a field in the *Options
-// message called uninterpreted_option. This field must have the same name
-// across all *Options messages. We then use this field to populate the
-// extensions when we build a descriptor, at which point all protos have been
-// parsed and so all extensions are known.
-//
-// Extension numbers for custom options may be chosen as follows:
-// * For options which will only be used within a single application or
-//   organization, or for experimental options, use field numbers 50000
-//   through 99999.  It is up to you to ensure that you do not use the
-//   same number for multiple options.
-// * For options which will be published and used publicly by multiple
-//   independent entities, e-mail protobuf-global-extension-registry@google.com
-//   to reserve extension numbers. Simply provide your project name (e.g.
-//   Objective-C plugin) and your project website (if available) -- there's no
-//   need to explain how you intend to use them. Usually you only need one
-//   extension number. You can declare multiple options with only one extension
-//   number by putting them in a sub-message. See the Custom Options section of
-//   the docs for examples:
-//   https://developers.google.com/protocol-buffers/docs/proto#options
-//   If this turns out to be popular, a web service will be set up
-//   to automatically assign option numbers.
-
-
-message FileOptions {
-
-  // Sets the Java package where classes generated from this .proto will be
-  // placed.  By default, the proto package is used, but this is often
-  // inappropriate because proto packages do not normally start with backwards
-  // domain names.
-  optional string java_package = 1;
-
-
-  // If set, all the classes from the .proto file are wrapped in a single
-  // outer class with the given name.  This applies to both Proto1
-  // (equivalent to the old "--one_java_file" option) and Proto2 (where
-  // a .proto always translates to a single class, but you may want to
-  // explicitly choose the class name).
-  optional string java_outer_classname = 8;
-
-  // If set true, then the Java code generator will generate a separate .java
-  // file for each top-level message, enum, and service defined in the .proto
-  // file.  Thus, these types will *not* be nested inside the outer class
-  // named by java_outer_classname.  However, the outer class will still be
-  // generated to contain the file's getDescriptor() method as well as any
-  // top-level extensions defined in the file.
-  optional bool java_multiple_files = 10 [default=false];
-
-  // This option does nothing.
-  optional bool java_generate_equals_and_hash = 20 [deprecated=true];
-
-  // If set true, then the Java2 code generator will generate code that
-  // throws an exception whenever an attempt is made to assign a non-UTF-8
-  // byte sequence to a string field.
-  // Message reflection will do the same.
-  // However, an extension field still accepts non-UTF-8 byte sequences.
-  // This option has no effect on when used with the lite runtime.
-  optional bool java_string_check_utf8 = 27 [default=false];
-
-
-  // Generated classes can be optimized for speed or code size.
-  enum OptimizeMode {
-    SPEED = 1;        // Generate complete code for parsing, serialization,
-                      // etc.
-    CODE_SIZE = 2;    // Use ReflectionOps to implement these methods.
-    LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime.
-  }
-  optional OptimizeMode optimize_for = 9 [default=SPEED];
-
-  // Sets the Go package where structs generated from this .proto will be
-  // placed. If omitted, the Go package will be derived from the following:
-  //   - The basename of the package import path, if provided.
-  //   - Otherwise, the package statement in the .proto file, if present.
-  //   - Otherwise, the basename of the .proto file, without extension.
-  optional string go_package = 11;
-
-
-
-  // Should generic services be generated in each language?  "Generic" services
-  // are not specific to any particular RPC system.  They are generated by the
-  // main code generators in each language (without additional plugins).
-  // Generic services were the only kind of service generation supported by
-  // early versions of google.protobuf.
-  //
-  // Generic services are now considered deprecated in favor of using plugins
-  // that generate code specific to your particular RPC system.  Therefore,
-  // these default to false.  Old code which depends on generic services should
-  // explicitly set them to true.
-  optional bool cc_generic_services = 16 [default=false];
-  optional bool java_generic_services = 17 [default=false];
-  optional bool py_generic_services = 18 [default=false];
-  optional bool php_generic_services = 42 [default=false];
-
-  // Is this file deprecated?
-  // Depending on the target platform, this can emit Deprecated annotations
-  // for everything in the file, or it will be completely ignored; in the very
-  // least, this is a formalization for deprecating files.
-  optional bool deprecated = 23 [default=false];
-
-  // Enables the use of arenas for the proto messages in this file. This applies
-  // only to generated classes for C++.
-  optional bool cc_enable_arenas = 31 [default=false];
-
-
-  // Sets the objective c class prefix which is prepended to all objective c
-  // generated classes from this .proto. There is no default.
-  optional string objc_class_prefix = 36;
-
-  // Namespace for generated classes; defaults to the package.
-  optional string csharp_namespace = 37;
-
-  // By default Swift generators will take the proto package and CamelCase it
-  // replacing '.' with underscore and use that to prefix the types/symbols
-  // defined. When this options is provided, they will use this value instead
-  // to prefix the types/symbols defined.
-  optional string swift_prefix = 39;
-
-  // Sets the php class prefix which is prepended to all php generated classes
-  // from this .proto. Default is empty.
-  optional string php_class_prefix = 40;
-
-  // Use this option to change the namespace of php generated classes. Default
-  // is empty. When this option is empty, the package name will be used for
-  // determining the namespace.
-  optional string php_namespace = 41;
-
-
-  // Use this option to change the namespace of php generated metadata classes.
-  // Default is empty. When this option is empty, the proto file name will be used
-  // for determining the namespace.
-  optional string php_metadata_namespace = 44;
-
-  // Use this option to change the package of ruby generated classes. Default
-  // is empty. When this option is not set, the package name will be used for
-  // determining the ruby package.
-  optional string ruby_package = 45;
-
-  // The parser stores options it doesn't recognize here.
-  // See the documentation for the "Options" section above.
-  repeated UninterpretedOption uninterpreted_option = 999;
-
-  // Clients can define custom options in extensions of this message.
-  // See the documentation for the "Options" section above.
-  extensions 1000 to max;
-
-  reserved 38;
-}
-
-message MessageOptions {
-  // Set true to use the old proto1 MessageSet wire format for extensions.
-  // This is provided for backwards-compatibility with the MessageSet wire
-  // format.  You should not use this for any other reason:  It's less
-  // efficient, has fewer features, and is more complicated.
-  //
-  // The message must be defined exactly as follows:
-  //   message Foo {
-  //     option message_set_wire_format = true;
-  //     extensions 4 to max;
-  //   }
-  // Note that the message cannot have any defined fields; MessageSets only
-  // have extensions.
-  //
-  // All extensions of your type must be singular messages; e.g. they cannot
-  // be int32s, enums, or repeated messages.
-  //
-  // Because this is an option, the above two restrictions are not enforced by
-  // the protocol compiler.
-  optional bool message_set_wire_format = 1 [default=false];
-
-  // Disables the generation of the standard "descriptor()" accessor, which can
-  // conflict with a field of the same name.  This is meant to make migration
-  // from proto1 easier; new code should avoid fields named "descriptor".
-  optional bool no_standard_descriptor_accessor = 2 [default=false];
-
-  // Is this message deprecated?
-  // Depending on the target platform, this can emit Deprecated annotations
-  // for the message, or it will be completely ignored; in the very least,
-  // this is a formalization for deprecating messages.
-  optional bool deprecated = 3 [default=false];
-
-  // Whether the message is an automatically generated map entry type for the
-  // maps field.
-  //
-  // For maps fields:
-  //     map<KeyType, ValueType> map_field = 1;
-  // The parsed descriptor looks like:
-  //     message MapFieldEntry {
-  //         option map_entry = true;
-  //         optional KeyType key = 1;
-  //         optional ValueType value = 2;
-  //     }
-  //     repeated MapFieldEntry map_field = 1;
-  //
-  // Implementations may choose not to generate the map_entry=true message, but
-  // use a native map in the target language to hold the keys and values.
-  // The reflection APIs in such implementions still need to work as
-  // if the field is a repeated message field.
-  //
-  // NOTE: Do not set the option in .proto files. Always use the maps syntax
-  // instead. The option should only be implicitly set by the proto compiler
-  // parser.
-  optional bool map_entry = 7;
-
-  reserved 8;  // javalite_serializable
-  reserved 9;  // javanano_as_lite
-
-  // The parser stores options it doesn't recognize here. See above.
-  repeated UninterpretedOption uninterpreted_option = 999;
-
-  // Clients can define custom options in extensions of this message. See above.
-  extensions 1000 to max;
-}
-
-message FieldOptions {
-  // The ctype option instructs the C++ code generator to use a different
-  // representation of the field than it normally would.  See the specific
-  // options below.  This option is not yet implemented in the open source
-  // release -- sorry, we'll try to include it in a future version!
-  optional CType ctype = 1 [default = STRING];
-  enum CType {
-    // Default mode.
-    STRING = 0;
-
-    CORD = 1;
-
-    STRING_PIECE = 2;
-  }
-  // The packed option can be enabled for repeated primitive fields to enable
-  // a more efficient representation on the wire. Rather than repeatedly
-  // writing the tag and type for each element, the entire array is encoded as
-  // a single length-delimited blob. In proto3, only explicit setting it to
-  // false will avoid using packed encoding.
-  optional bool packed = 2;
-
-  // The jstype option determines the JavaScript type used for values of the
-  // field.  The option is permitted only for 64 bit integral and fixed types
-  // (int64, uint64, sint64, fixed64, sfixed64).  A field with jstype JS_STRING
-  // is represented as JavaScript string, which avoids loss of precision that
-  // can happen when a large value is converted to a floating point JavaScript.
-  // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
-  // use the JavaScript "number" type.  The behavior of the default option
-  // JS_NORMAL is implementation dependent.
-  //
-  // This option is an enum to permit additional types to be added, e.g.
-  // goog.math.Integer.
-  optional JSType jstype = 6 [default = JS_NORMAL];
-  enum JSType {
-    // Use the default type.
-    JS_NORMAL = 0;
-
-    // Use JavaScript strings.
-    JS_STRING = 1;
-
-    // Use JavaScript numbers.
-    JS_NUMBER = 2;
-  }
-
-  // Should this field be parsed lazily?  Lazy applies only to message-type
-  // fields.  It means that when the outer message is initially parsed, the
-  // inner message's contents will not be parsed but instead stored in encoded
-  // form.  The inner message will actually be parsed when it is first accessed.
-  //
-  // This is only a hint.  Implementations are free to choose whether to use
-  // eager or lazy parsing regardless of the value of this option.  However,
-  // setting this option true suggests that the protocol author believes that
-  // using lazy parsing on this field is worth the additional bookkeeping
-  // overhead typically needed to implement it.
-  //
-  // This option does not affect the public interface of any generated code;
-  // all method signatures remain the same.  Furthermore, thread-safety of the
-  // interface is not affected by this option; const methods remain safe to
-  // call from multiple threads concurrently, while non-const methods continue
-  // to require exclusive access.
-  //
-  //
-  // Note that implementations may choose not to check required fields within
-  // a lazy sub-message.  That is, calling IsInitialized() on the outer message
-  // may return true even if the inner message has missing required fields.
-  // This is necessary because otherwise the inner message would have to be
-  // parsed in order to perform the check, defeating the purpose of lazy
-  // parsing.  An implementation which chooses not to check required fields
-  // must be consistent about it.  That is, for any particular sub-message, the
-  // implementation must either *always* check its required fields, or *never*
-  // check its required fields, regardless of whether or not the message has
-  // been parsed.
-  optional bool lazy = 5 [default=false];
-
-  // Is this field deprecated?
-  // Depending on the target platform, this can emit Deprecated annotations
-  // for accessors, or it will be completely ignored; in the very least, this
-  // is a formalization for deprecating fields.
-  optional bool deprecated = 3 [default=false];
-
-  // For Google-internal migration only. Do not use.
-  optional bool weak = 10 [default=false];
-
-
-  // The parser stores options it doesn't recognize here. See above.
-  repeated UninterpretedOption uninterpreted_option = 999;
-
-  // Clients can define custom options in extensions of this message. See above.
-  extensions 1000 to max;
-
-  reserved 4;  // removed jtype
-}
-
-message OneofOptions {
-  // The parser stores options it doesn't recognize here. See above.
-  repeated UninterpretedOption uninterpreted_option = 999;
-
-  // Clients can define custom options in extensions of this message. See above.
-  extensions 1000 to max;
-}
-
-message EnumOptions {
-
-  // Set this option to true to allow mapping different tag names to the same
-  // value.
-  optional bool allow_alias = 2;
-
-  // Is this enum deprecated?
-  // Depending on the target platform, this can emit Deprecated annotations
-  // for the enum, or it will be completely ignored; in the very least, this
-  // is a formalization for deprecating enums.
-  optional bool deprecated = 3 [default=false];
-
-  reserved 5;  // javanano_as_lite
-
-  // The parser stores options it doesn't recognize here. See above.
-  repeated UninterpretedOption uninterpreted_option = 999;
-
-  // Clients can define custom options in extensions of this message. See above.
-  extensions 1000 to max;
-}
-
-message EnumValueOptions {
-  // Is this enum value deprecated?
-  // Depending on the target platform, this can emit Deprecated annotations
-  // for the enum value, or it will be completely ignored; in the very least,
-  // this is a formalization for deprecating enum values.
-  optional bool deprecated = 1 [default=false];
-
-  // The parser stores options it doesn't recognize here. See above.
-  repeated UninterpretedOption uninterpreted_option = 999;
-
-  // Clients can define custom options in extensions of this message. See above.
-  extensions 1000 to max;
-}
-
-message ServiceOptions {
-
-  // Note:  Field numbers 1 through 32 are reserved for Google's internal RPC
-  //   framework.  We apologize for hoarding these numbers to ourselves, but
-  //   we were already using them long before we decided to release Protocol
-  //   Buffers.
-
-  // Is this service deprecated?
-  // Depending on the target platform, this can emit Deprecated annotations
-  // for the service, or it will be completely ignored; in the very least,
-  // this is a formalization for deprecating services.
-  optional bool deprecated = 33 [default=false];
-
-  // The parser stores options it doesn't recognize here. See above.
-  repeated UninterpretedOption uninterpreted_option = 999;
-
-  // Clients can define custom options in extensions of this message. See above.
-  extensions 1000 to max;
-}
-
-message MethodOptions {
-
-  // Note:  Field numbers 1 through 32 are reserved for Google's internal RPC
-  //   framework.  We apologize for hoarding these numbers to ourselves, but
-  //   we were already using them long before we decided to release Protocol
-  //   Buffers.
-
-  // Is this method deprecated?
-  // Depending on the target platform, this can emit Deprecated annotations
-  // for the method, or it will be completely ignored; in the very least,
-  // this is a formalization for deprecating methods.
-  optional bool deprecated = 33 [default=false];
-
-  // Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
-  // or neither? HTTP based RPC implementation may choose GET verb for safe
-  // methods, and PUT verb for idempotent methods instead of the default POST.
-  enum IdempotencyLevel {
-    IDEMPOTENCY_UNKNOWN = 0;
-    NO_SIDE_EFFECTS     = 1; // implies idempotent
-    IDEMPOTENT          = 2; // idempotent, but may have side effects
-  }
-  optional IdempotencyLevel idempotency_level =
-      34 [default=IDEMPOTENCY_UNKNOWN];
-
-  // The parser stores options it doesn't recognize here. See above.
-  repeated UninterpretedOption uninterpreted_option = 999;
-
-  // Clients can define custom options in extensions of this message. See above.
-  extensions 1000 to max;
-}
-
-
-// A message representing a option the parser does not recognize. This only
-// appears in options protos created by the compiler::Parser class.
-// DescriptorPool resolves these when building Descriptor objects. Therefore,
-// options protos in descriptor objects (e.g. returned by Descriptor::options(),
-// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
-// in them.
-message UninterpretedOption {
-  // The name of the uninterpreted option.  Each string represents a segment in
-  // a dot-separated name.  is_extension is true iff a segment represents an
-  // extension (denoted with parentheses in options specs in .proto files).
-  // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
-  // "foo.(bar.baz).qux".
-  message NamePart {
-    required string name_part = 1;
-    required bool is_extension = 2;
-  }
-  repeated NamePart name = 2;
-
-  // The value of the uninterpreted option, in whatever type the tokenizer
-  // identified it as during parsing. Exactly one of these should be set.
-  optional string identifier_value = 3;
-  optional uint64 positive_int_value = 4;
-  optional int64 negative_int_value = 5;
-  optional double double_value = 6;
-  optional bytes string_value = 7;
-  optional string aggregate_value = 8;
-}
-
-// ===================================================================
-// Optional source code info
-
-// Encapsulates information about the original source file from which a
-// FileDescriptorProto was generated.
-message SourceCodeInfo {
-  // A Location identifies a piece of source code in a .proto file which
-  // corresponds to a particular definition.  This information is intended
-  // to be useful to IDEs, code indexers, documentation generators, and similar
-  // tools.
-  //
-  // For example, say we have a file like:
-  //   message Foo {
-  //     optional string foo = 1;
-  //   }
-  // Let's look at just the field definition:
-  //   optional string foo = 1;
-  //   ^       ^^     ^^  ^  ^^^
-  //   a       bc     de  f  ghi
-  // We have the following locations:
-  //   span   path               represents
-  //   [a,i)  [ 4, 0, 2, 0 ]     The whole field definition.
-  //   [a,b)  [ 4, 0, 2, 0, 4 ]  The label (optional).
-  //   [c,d)  [ 4, 0, 2, 0, 5 ]  The type (string).
-  //   [e,f)  [ 4, 0, 2, 0, 1 ]  The name (foo).
-  //   [g,h)  [ 4, 0, 2, 0, 3 ]  The number (1).
-  //
-  // Notes:
-  // - A location may refer to a repeated field itself (i.e. not to any
-  //   particular index within it).  This is used whenever a set of elements are
-  //   logically enclosed in a single code segment.  For example, an entire
-  //   extend block (possibly containing multiple extension definitions) will
-  //   have an outer location whose path refers to the "extensions" repeated
-  //   field without an index.
-  // - Multiple locations may have the same path.  This happens when a single
-  //   logical declaration is spread out across multiple places.  The most
-  //   obvious example is the "extend" block again -- there may be multiple
-  //   extend blocks in the same scope, each of which will have the same path.
-  // - A location's span is not always a subset of its parent's span.  For
-  //   example, the "extendee" of an extension declaration appears at the
-  //   beginning of the "extend" block and is shared by all extensions within
-  //   the block.
-  // - Just because a location's span is a subset of some other location's span
-  //   does not mean that it is a descendent.  For example, a "group" defines
-  //   both a type and a field in a single declaration.  Thus, the locations
-  //   corresponding to the type and field and their components will overlap.
-  // - Code which tries to interpret locations should probably be designed to
-  //   ignore those that it doesn't understand, as more types of locations could
-  //   be recorded in the future.
-  repeated Location location = 1;
-  message Location {
-    // Identifies which part of the FileDescriptorProto was defined at this
-    // location.
-    //
-    // Each element is a field number or an index.  They form a path from
-    // the root FileDescriptorProto to the place where the definition.  For
-    // example, this path:
-    //   [ 4, 3, 2, 7, 1 ]
-    // refers to:
-    //   file.message_type(3)  // 4, 3
-    //       .field(7)         // 2, 7
-    //       .name()           // 1
-    // This is because FileDescriptorProto.message_type has field number 4:
-    //   repeated DescriptorProto message_type = 4;
-    // and DescriptorProto.field has field number 2:
-    //   repeated FieldDescriptorProto field = 2;
-    // and FieldDescriptorProto.name has field number 1:
-    //   optional string name = 1;
-    //
-    // Thus, the above path gives the location of a field name.  If we removed
-    // the last element:
-    //   [ 4, 3, 2, 7 ]
-    // this path refers to the whole field declaration (from the beginning
-    // of the label to the terminating semicolon).
-    repeated int32 path = 1 [packed=true];
-
-    // Always has exactly three or four elements: start line, start column,
-    // end line (optional, otherwise assumed same as start line), end column.
-    // These are packed into a single field for efficiency.  Note that line
-    // and column numbers are zero-based -- typically you will want to add
-    // 1 to each before displaying to a user.
-    repeated int32 span = 2 [packed=true];
-
-    // If this SourceCodeInfo represents a complete declaration, these are any
-    // comments appearing before and after the declaration which appear to be
-    // attached to the declaration.
-    //
-    // A series of line comments appearing on consecutive lines, with no other
-    // tokens appearing on those lines, will be treated as a single comment.
-    //
-    // leading_detached_comments will keep paragraphs of comments that appear
-    // before (but not connected to) the current element. Each paragraph,
-    // separated by empty lines, will be one comment element in the repeated
-    // field.
-    //
-    // Only the comment content is provided; comment markers (e.g. //) are
-    // stripped out.  For block comments, leading whitespace and an asterisk
-    // will be stripped from the beginning of each line other than the first.
-    // Newlines are included in the output.
-    //
-    // Examples:
-    //
-    //   optional int32 foo = 1;  // Comment attached to foo.
-    //   // Comment attached to bar.
-    //   optional int32 bar = 2;
-    //
-    //   optional string baz = 3;
-    //   // Comment attached to baz.
-    //   // Another line attached to baz.
-    //
-    //   // Comment attached to qux.
-    //   //
-    //   // Another line attached to qux.
-    //   optional double qux = 4;
-    //
-    //   // Detached comment for corge. This is not leading or trailing comments
-    //   // to qux or corge because there are blank lines separating it from
-    //   // both.
-    //
-    //   // Detached comment for corge paragraph 2.
-    //
-    //   optional string corge = 5;
-    //   /* Block comment attached
-    //    * to corge.  Leading asterisks
-    //    * will be removed. */
-    //   /* Block comment attached to
-    //    * grault. */
-    //   optional int32 grault = 6;
-    //
-    //   // ignored detached comments.
-    optional string leading_comments = 3;
-    optional string trailing_comments = 4;
-    repeated string leading_detached_comments = 6;
-  }
-}
-
-// Describes the relationship between generated code and its original source
-// file. A GeneratedCodeInfo message is associated with only one generated
-// source file, but may contain references to different source .proto files.
-message GeneratedCodeInfo {
-  // An Annotation connects some span of text in generated code to an element
-  // of its generating .proto file.
-  repeated Annotation annotation = 1;
-  message Annotation {
-    // Identifies the element in the original source .proto file. This field
-    // is formatted the same as SourceCodeInfo.Location.path.
-    repeated int32 path = 1 [packed=true];
-
-    // Identifies the filesystem path to the original source .proto.
-    optional string source_file = 2;
-
-    // Identifies the starting offset in bytes in the generated code
-    // that relates to the identified object.
-    optional int32 begin = 3;
-
-    // Identifies the ending offset in bytes in the generated code that
-    // relates to the identified offset. The end offset should be one past
-    // the last relevant byte (so the length of the text = end - begin).
-    optional int32 end = 4;
-  }
-}
diff --git a/proto/google/protobuf/duration.proto b/proto/google/protobuf/duration.proto
deleted file mode 100644
index 975fce4..0000000
--- a/proto/google/protobuf/duration.proto
+++ /dev/null
@@ -1,117 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-
-package google.protobuf;
-
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option cc_enable_arenas = true;
-option go_package = "github.com/golang/protobuf/ptypes/duration";
-option java_package = "com.google.protobuf";
-option java_outer_classname = "DurationProto";
-option java_multiple_files = true;
-option objc_class_prefix = "GPB";
-
-// A Duration represents a signed, fixed-length span of time represented
-// as a count of seconds and fractions of seconds at nanosecond
-// resolution. It is independent of any calendar and concepts like "day"
-// or "month". It is related to Timestamp in that the difference between
-// two Timestamp values is a Duration and it can be added or subtracted
-// from a Timestamp. Range is approximately +-10,000 years.
-//
-// # Examples
-//
-// Example 1: Compute Duration from two Timestamps in pseudo code.
-//
-//     Timestamp start = ...;
-//     Timestamp end = ...;
-//     Duration duration = ...;
-//
-//     duration.seconds = end.seconds - start.seconds;
-//     duration.nanos = end.nanos - start.nanos;
-//
-//     if (duration.seconds < 0 && duration.nanos > 0) {
-//       duration.seconds += 1;
-//       duration.nanos -= 1000000000;
-//     } else if (durations.seconds > 0 && duration.nanos < 0) {
-//       duration.seconds -= 1;
-//       duration.nanos += 1000000000;
-//     }
-//
-// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
-//
-//     Timestamp start = ...;
-//     Duration duration = ...;
-//     Timestamp end = ...;
-//
-//     end.seconds = start.seconds + duration.seconds;
-//     end.nanos = start.nanos + duration.nanos;
-//
-//     if (end.nanos < 0) {
-//       end.seconds -= 1;
-//       end.nanos += 1000000000;
-//     } else if (end.nanos >= 1000000000) {
-//       end.seconds += 1;
-//       end.nanos -= 1000000000;
-//     }
-//
-// Example 3: Compute Duration from datetime.timedelta in Python.
-//
-//     td = datetime.timedelta(days=3, minutes=10)
-//     duration = Duration()
-//     duration.FromTimedelta(td)
-//
-// # JSON Mapping
-//
-// In JSON format, the Duration type is encoded as a string rather than an
-// object, where the string ends in the suffix "s" (indicating seconds) and
-// is preceded by the number of seconds, with nanoseconds expressed as
-// fractional seconds. For example, 3 seconds with 0 nanoseconds should be
-// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should
-// be expressed in JSON format as "3.000000001s", and 3 seconds and 1
-// microsecond should be expressed in JSON format as "3.000001s".
-//
-//
-message Duration {
-
-  // Signed seconds of the span of time. Must be from -315,576,000,000
-  // to +315,576,000,000 inclusive. Note: these bounds are computed from:
-  // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
-  int64 seconds = 1;
-
-  // Signed fractions of a second at nanosecond resolution of the span
-  // of time. Durations less than one second are represented with a 0
-  // `seconds` field and a positive or negative `nanos` field. For durations
-  // of one second or more, a non-zero value for the `nanos` field must be
-  // of the same sign as the `seconds` field. Must be from -999,999,999
-  // to +999,999,999 inclusive.
-  int32 nanos = 2;
-}
diff --git a/proto/google/protobuf/empty.proto b/proto/google/protobuf/empty.proto
deleted file mode 100644
index 03cacd2..0000000
--- a/proto/google/protobuf/empty.proto
+++ /dev/null
@@ -1,52 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-
-package google.protobuf;
-
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option go_package = "github.com/golang/protobuf/ptypes/empty";
-option java_package = "com.google.protobuf";
-option java_outer_classname = "EmptyProto";
-option java_multiple_files = true;
-option objc_class_prefix = "GPB";
-option cc_enable_arenas = true;
-
-// A generic empty message that you can re-use to avoid defining duplicated
-// empty messages in your APIs. A typical example is to use it as the request
-// or the response type of an API method. For instance:
-//
-//     service Foo {
-//       rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
-//     }
-//
-// The JSON representation for `Empty` is empty JSON object `{}`.
-message Empty {}
diff --git a/proto/google/rpc/status.proto b/proto/google/rpc/status.proto
deleted file mode 100644
index 0839ee9..0000000
--- a/proto/google/rpc/status.proto
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2017 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-syntax = "proto3";
-
-package google.rpc;
-
-import "google/protobuf/any.proto";
-
-option go_package = "google.golang.org/genproto/googleapis/rpc/status;status";
-option java_multiple_files = true;
-option java_outer_classname = "StatusProto";
-option java_package = "com.google.rpc";
-option objc_class_prefix = "RPC";
-
-
-// The `Status` type defines a logical error model that is suitable for different
-// programming environments, including REST APIs and RPC APIs. It is used by
-// [gRPC](https://github.com/grpc). The error model is designed to be:
-//
-// - Simple to use and understand for most users
-// - Flexible enough to meet unexpected needs
-//
-// # Overview
-//
-// The `Status` message contains three pieces of data: error code, error message,
-// and error details. The error code should be an enum value of
-// [google.rpc.Code][google.rpc.Code], but it may accept additional error codes if needed.  The
-// error message should be a developer-facing English message that helps
-// developers *understand* and *resolve* the error. If a localized user-facing
-// error message is needed, put the localized message in the error details or
-// localize it in the client. The optional error details may contain arbitrary
-// information about the error. There is a predefined set of error detail types
-// in the package `google.rpc` that can be used for common error conditions.
-//
-// # Language mapping
-//
-// The `Status` message is the logical representation of the error model, but it
-// is not necessarily the actual wire format. When the `Status` message is
-// exposed in different client libraries and different wire protocols, it can be
-// mapped differently. For example, it will likely be mapped to some exceptions
-// in Java, but more likely mapped to some error codes in C.
-//
-// # Other uses
-//
-// The error model and the `Status` message can be used in a variety of
-// environments, either with or without APIs, to provide a
-// consistent developer experience across different environments.
-//
-// Example uses of this error model include:
-//
-// - Partial errors. If a service needs to return partial errors to the client,
-//     it may embed the `Status` in the normal response to indicate the partial
-//     errors.
-//
-// - Workflow errors. A typical workflow has multiple steps. Each step may
-//     have a `Status` message for error reporting.
-//
-// - Batch operations. If a client uses batch request and batch response, the
-//     `Status` message should be used directly inside batch response, one for
-//     each error sub-response.
-//
-// - Asynchronous operations. If an API call embeds asynchronous operation
-//     results in its response, the status of those operations should be
-//     represented directly using the `Status` message.
-//
-// - Logging. If some API errors are stored in logs, the message `Status` could
-//     be used directly after any stripping needed for security/privacy reasons.
-message Status {
-  // The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code].
-  int32 code = 1;
-
-  // A developer-facing error message, which should be in English. Any
-  // user-facing error message should be localized and sent in the
-  // [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client.
-  string message = 2;
-
-  // A list of messages that carry the error details.  There is a common set of
-  // message types for APIs to use.
-  repeated google.protobuf.Any details = 3;
-}
diff --git a/remoteexec/adapter_test.go b/remoteexec/adapter_test.go
index 7ed49a9..3f31caf 100644
--- a/remoteexec/adapter_test.go
+++ b/remoteexec/adapter_test.go
@@ -20,6 +20,7 @@
 	bpb "google.golang.org/genproto/googleapis/bytestream"
 
 	gomapb "go.chromium.org/goma/server/proto/api"
+	cachepb "go.chromium.org/goma/server/proto/cache"
 	cmdpb "go.chromium.org/goma/server/proto/command"
 	fpb "go.chromium.org/goma/server/proto/file"
 	"go.chromium.org/goma/server/remoteexec/cas"
@@ -181,6 +182,144 @@
 	}
 }
 
+func TestAdapterHandleMissingInputFilename(t *testing.T) {
+	// http://b/132391933 should not get filename from digest_cache.
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+
+	cluster := &fakeCluster{
+		rbe: newFakeRBE(),
+	}
+	err := cluster.setup(ctx, cluster.rbe.instancePrefix)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer cluster.teardown()
+
+	clang := newFakeClang(&cluster.cmdStorage, "1234", "x86-64-linux-gnu")
+
+	err = cluster.pushToolchains(ctx, clang)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	var localFiles fakeLocalFiles
+	localFiles.Add("/b/c/w/src/hello.cc", randomSize())
+	localFiles.Add("/b/c/w/include/hello.h", randomSize())
+
+	req := &gomapb.ExecReq{
+		CommandSpec: clang.CommandSpec("clang", "bin/clang"),
+		Arg: []string{
+			"bin/clang", "-I../../include",
+			"-c", "../../src/hello.cc",
+		},
+		Env: []string{},
+		Cwd: proto.String("/b/c/w/out/Release"),
+		Input: []*gomapb.ExecReq_Input{
+			localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/b/c/w/src/hello.cc", "../../src/hello.cc"),
+			localFiles.mustInput(ctx, t, cluster.adapter.GomaFile, "/b/c/w/include/hello.h", "../../include/hello.h"),
+		},
+		Subprogram:    []*gomapb.SubprogramSpec{},
+		RequesterInfo: &gomapb.RequesterInfo{},
+		HermeticMode:  proto.Bool(true),
+	}
+
+	t.Logf("first call")
+	resp, err := cluster.adapter.Exec(ctx, req)
+	if err != nil {
+		t.Fatalf("Exec(ctx, req)=%v; %v; want nil error", resp, err)
+	}
+	if resp.GetError() != gomapb.ExecResp_OK {
+		t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_OK)
+	}
+	if len(resp.MissingInput) > 0 {
+		t.Fatalf("missing=%v; want no missing", resp.MissingInput)
+	}
+
+	t.Logf("clear in-memory digest cache, but still in redis.")
+	cluster.adapter.DigestCache = digest.NewCache(&cluster.redis)
+
+	req = &gomapb.ExecReq{
+		CommandSpec: clang.CommandSpec("clang", "bin/clang"),
+		Arg: []string{
+			"bin/clang", "-I../../include",
+			"-c", "../../src/hello.cc",
+		},
+		Env: []string{},
+		Cwd: proto.String("/b/c/w/out/Release"),
+		Input: []*gomapb.ExecReq_Input{
+			localFiles.mustInput(ctx, t, nil, "/b/c/w/src/hello.cc", "../../src/hello.cc"),
+			localFiles.mustInput(ctx, t, nil, "/b/c/w/include/hello.h", "../../include/hello.h"),
+		},
+		Subprogram:    []*gomapb.SubprogramSpec{},
+		RequesterInfo: &gomapb.RequesterInfo{},
+		HermeticMode:  proto.Bool(true),
+	}
+	t.Logf("second call, clear in-memory content in digest cache")
+	resp, err = cluster.adapter.Exec(ctx, req)
+	if err != nil {
+		t.Fatalf("Exec(ctx, req)=%v; %v; want nil error", resp, err)
+	}
+	if resp.GetError() != gomapb.ExecResp_OK {
+		t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_OK)
+	}
+	if len(resp.MissingInput) > 0 {
+		t.Fatalf("missing=%v; want no missing", resp.MissingInput)
+	}
+
+	localFiles.Dup("/b/c/w/src/hello.cc", "/b/c/w/src/hello2.cc")
+	localFiles.Dup("/b/c/w/include/hello.h", "/b/c/w/include/hello2.h")
+
+	req = &gomapb.ExecReq{
+		CommandSpec: clang.CommandSpec("clang", "bin/clang"),
+		Arg: []string{
+			"bin/clang", "-I../../include",
+			"-c", "../../src/hello2.cc",
+		},
+		Env: []string{},
+		Cwd: proto.String("/b/c/w/out/Release"),
+		Input: []*gomapb.ExecReq_Input{
+			// client sends hash only (fc==nil).
+			localFiles.mustInput(ctx, t, nil, "/b/c/w/src/hello2.cc", "../../src/hello2.cc"),
+			localFiles.mustInput(ctx, t, nil, "/b/c/w/include/hello2.h", "../../include/hello2.h"),
+		},
+		Subprogram:    []*gomapb.SubprogramSpec{},
+		RequesterInfo: &gomapb.RequesterInfo{},
+		HermeticMode:  proto.Bool(true),
+	}
+	t.Logf("reset cas and file-server cache")
+	cluster.rbe.cas = digest.NewStore()
+	for _, input := range req.Input {
+		_, err = cluster.cache.Put(ctx, &cachepb.PutReq{
+			Kv: &cachepb.KV{
+				Key: input.GetHashKey(),
+			},
+		})
+		if err != nil {
+			t.Fatalf("reset cache %s: %v", input, err)
+		}
+	}
+
+	t.Logf("third call, different filename")
+
+	resp, err = cluster.adapter.Exec(ctx, req)
+	if err != nil {
+		t.Fatalf("Exec(ctx, req)=%v; %v; want nil error", resp, err)
+	}
+	if resp.GetError() != gomapb.ExecResp_OK {
+		t.Errorf("Exec error=%v; want=%v", resp.GetError(), gomapb.ExecResp_OK)
+	}
+
+	wantMissing := []string{"../../src/hello2.cc", "../../include/hello2.h"}
+
+	if !cmp.Equal(resp.MissingInput, wantMissing) {
+		t.Fatalf("missing=%v; want=%v", resp.MissingInput, wantMissing)
+	}
+	if len(resp.MissingInput) != len(resp.MissingReason) {
+		t.Fatalf("missing: len(input)=%d != len(reason)=%d", len(resp.MissingInput), len(resp.MissingReason))
+	}
+}
+
 func TestAdapterHandleMissingInputContents(t *testing.T) {
 	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 	defer cancel()
@@ -737,7 +876,7 @@
 		Subprogram:        []*gomapb.SubprogramSpec{},
 		ToolchainIncluded: proto.Bool(true),
 		ToolchainSpecs: []*gomapb.ToolchainSpec{
-			&gomapb.ToolchainSpec{
+			{
 				Path:         proto.String("../../bin/clang"),
 				Hash:         proto.String(clangHashKey),
 				Size:         clangToolchainInput.Content.FileSize,
@@ -865,7 +1004,7 @@
 		Subprogram:        []*gomapb.SubprogramSpec{},
 		ToolchainIncluded: proto.Bool(true),
 		ToolchainSpecs: []*gomapb.ToolchainSpec{
-			&gomapb.ToolchainSpec{
+			{
 				Path:         proto.String("../../bin/clang"),
 				Hash:         proto.String(clangHashKey),
 				Size:         clangToolchainInput.Content.FileSize,
diff --git a/remoteexec/client.go b/remoteexec/client.go
index 9eaae09..e691349 100644
--- a/remoteexec/client.go
+++ b/remoteexec/client.go
@@ -32,7 +32,7 @@
 		stats.UnitDimensionless)
 
 	DefaultViews = []*view.View{
-		&view.View{
+		{
 			Description: `Number of current running exec operations`,
 			Measure:     numRunningOperations,
 			Aggregation: view.Sum(),
diff --git a/remoteexec/digest/digest_cache_test.go b/remoteexec/digest/digest_cache_test.go
new file mode 100644
index 0000000..254ee0a
--- /dev/null
+++ b/remoteexec/digest/digest_cache_test.go
@@ -0,0 +1,38 @@
+/* Copyright 2019 Google Inc. All Rights Reserved. */
+
+package digest
+
+import (
+	"context"
+	"testing"
+
+	"go.chromium.org/goma/server/cache"
+)
+
+func TestCacheGet(t *testing.T) {
+	c, err := cache.New(cache.Config{
+		MaxBytes: 1 * 1024 * 1024,
+	})
+	if err != nil {
+		t.Fatal(err)
+	}
+	dc := NewCache(cache.LocalClient{
+		CacheServiceServer: c,
+	})
+
+	ctx := context.Background()
+
+	want := Bytes("first", []byte{12})
+	_, err = dc.Get(ctx, "12", want)
+	if err != nil {
+		t.Fatalf("Get(ctx, 12, 'first')=%v; want nil error", err)
+	}
+
+	d2, err := dc.Get(ctx, "12", Bytes("second", []byte{12}))
+	if err != nil {
+		t.Fatalf("Get(ctx, 12, 'second')=%v; want nil error", err)
+	}
+	if d2.String() == want.String() {
+		t.Errorf("Get(ctx, 12, 'second')=%v; want %v", d2, want)
+	}
+}
diff --git a/remoteexec/exec.go b/remoteexec/exec.go
index 67eaff1..83a0557 100644
--- a/remoteexec/exec.go
+++ b/remoteexec/exec.go
@@ -58,7 +58,8 @@
 	action       *rpb.Action
 	actionDigest *rpb.Digest
 
-	needOverlay bool
+	allowChroot bool
+	needChroot  bool
 
 	err error
 }
@@ -195,6 +196,7 @@
 	for _, prop := range cmdConfig.GetRemoteexecPlatform().GetProperties() {
 		r.addPlatformProperty(ctx, prop.Name, prop.Value)
 	}
+	// TODO: set allow chroot if RemoteexecPlatform allows.
 	logger.Infof("platform: %s", r.platform)
 	return nil
 }
@@ -215,6 +217,15 @@
 	})
 }
 
+type inputDigestData struct {
+	filename string
+	digest.Data
+}
+
+func (id inputDigestData) String() string {
+	return fmt.Sprintf("%s %s", id.Data.String(), id.filename)
+}
+
 // newInputTree constructs input tree from req.
 // it returns non-nil ExecResp for:
 // - missing inputs
@@ -234,7 +245,7 @@
 		r.gomaResp.ErrorMessage = append(r.gomaResp.ErrorMessage, fmt.Sprintf("bad input: %v", err))
 		return r.gomaResp
 	}
-	rootDir, needOverlay, err := inputRootDir(r.filepath, inputPaths, false)
+	rootDir, needChroot, err := inputRootDir(r.filepath, inputPaths, r.allowChroot)
 	if err != nil {
 		logger.Errorf("input root detection failed: %v", err)
 		logFileList(logger, "input paths", inputPaths)
@@ -243,7 +254,7 @@
 		return r.gomaResp
 	}
 	r.tree = merkletree.New(r.filepath, rootDir, r.digestStore)
-	r.needOverlay = needOverlay
+	r.needChroot = needChroot
 
 	logger.Infof("new input tree cwd:%s root:%s %s", r.gomaReq.GetCwd(), r.tree.RootDir(), r.cmdConfig.GetCmdDescriptor().GetSetup().GetPathType())
 	gi := gomaInput{
@@ -339,10 +350,14 @@
 				})
 				return
 			}
+			logger.Debugf("input %s hash=%s digest=%s", input.GetFilename(), input.GetHashKey(), data.Digest())
 
 			file := merkletree.Entry{
-				Name:         fname,
-				Data:         data,
+				Name: fname,
+				Data: inputDigestData{
+					filename: input.GetFilename(),
+					Data:     data,
+				},
 				IsExecutable: executableInputs[input.GetFilename()],
 			}
 			if input.Content == nil {
@@ -511,13 +526,22 @@
 
 const (
 	wrapperScript = `#!/bin/bash
-# run command at the same dir as user.
-# it runs in sibling docker
+# run command (i.e. "$@") at the same dir as user.
+#  INPUT_ROOT_DIR: expected directory of input root.
+#    input root is current directory to run this script.
+#    need to mount input root on $INPUT_ROOT_DIR.
+#  WORK_DIR: working directory relative to INPUT_ROOT_DIR.
+#    command will run at $INPUT_ROOT_DIR/$WORK_DIR.
+#
+# by default, it runs in sibling docker (for Cloud RBE).
 #  with the same uid
 #  with current directory (input root) mounted as same path as user's input root
 #  with the same working directory as user
 #  with the same container image
 #  to run the command line as user requested.
+#
+# if /opt/goma/bin/run-at-dir.sh exists in contianer image, use it instead.
+# http://b/132742952
 set -e
 
 # check inputs.
@@ -530,6 +554,12 @@
   echo "ERROR: WORK_DIR is not set" >&2
   exit 1
 fi
+# if container image provides the script, use it instead.
+if [[ -x /opt/goma/bin/run-at-dir.sh ]]; then
+  exec /opt/goma/bin/run-at-dir.sh "$@"
+  echo "ERROR: exec /opt/goma/bin/run-at-dir.sh failed: $?" >&2
+  exit 1
+fi
 
 ## get container id
 containerid="$(basename "$(cat /proc/self/cpuset)")"
@@ -571,6 +601,60 @@
 fi
 exec "$@"
 `
+
+	chrootRunWrapperScript = `#!/bin/bash
+set -e
+
+if [[ "$WORK_DIR" == "" ]]; then
+  echo "ERROR: WORK_DIR is not set" >&2
+  exit 1
+fi
+
+rundir="$(pwd)"
+chroot_workdir="/tmp/goma_chroot"
+
+#
+# mount directories under $chroot_workdir and execute.
+#
+run_dirs=($(ls -1 "$rundir"))
+sys_dirs=(dev proc)
+
+# RBE server generates __action_home__XXXXXXXXXX directory in $rundir
+# (note: XXXXXXXXXX is a random).  Let's skip it because we do not use that.
+# mount directories in the request.
+for d in "${run_dirs[@]}"; do
+  if [[ "$d" == __action_home__* ]]; then
+    continue
+  fi
+  mkdir -p "$chroot_workdir/$d"
+  mount --bind "$rundir/$d" "$chroot_workdir/$d"
+done
+
+# mount directories not included in the request.
+for d in "${sys_dirs[@]}"; do
+  # avoid to mount system directories if that exist in the user's request.
+  if [[ -d "$rundir/$d" ]]; then
+    continue
+  fi
+  # workaround to make them read only mount with util-linux < 2.27.
+  mkdir -p "$chroot_workdir/$d"
+  mount --bind "/$d" "$chroot_workdir/$d"
+  mount "$chroot_workdir/$d" -o remount,ro,bind
+done
+
+# currently running with root. run the command with nobody:nogroup with chroot.
+# We use nsjail to chdir without running bash script inside chroot, and
+# libc inside chroot can be different from libc outside.
+# TODO: give nsjail rule with file.
+nsjail \
+  --user nobody:nobody \
+  --group nogroup:nogroup \
+  --chroot "$chroot_workdir" \
+  --cwd "$WORK_DIR" \
+  --rw \
+  --quiet \
+  -- "$@"
+`
 )
 
 // TODO: put wrapper script in platform container?
@@ -603,24 +687,35 @@
 	switch pathType {
 	case cmdpb.CmdDescriptor_POSIX:
 		var d digest.Data
-		err = cwdAgnosticReq(ctx, cmdConfig, r.filepath, r.gomaReq.Arg, r.gomaReq.Env)
-		if err != nil {
-			logger.Infof("non cwd agnostic: %v", err)
-			d = digest.Bytes("wrapper-script", []byte(wrapperScript))
-			envs = append(envs, fmt.Sprintf("INPUT_ROOT_DIR=%s", r.tree.RootDir()))
+		// TODO: use chroot for all ATS cases.
+		if r.needChroot {
+			logger.Infof("run with chroot")
 			envs = append(envs, r.gomaReq.Env...)
-			r.addPlatformProperty(ctx, "dockerSiblingContainers", "true")
+			// needed for bind mount.
+			r.addPlatformProperty(ctx, "dockerPrivileged", "true")
+			// needed for chroot command and mount command.
+			r.addPlatformProperty(ctx, "dockerRunAsRoot", "true")
+			d = digest.Bytes("chroot-run-wrapper-script", []byte(chrootRunWrapperScript))
 		} else {
-			logger.Infof("cwd agnostic")
-			d = digest.Bytes("cwd-agnostic-wrapper-script", []byte(cwdAgnosticWrapperScript))
-			for _, e := range r.gomaReq.Env {
-				if strings.HasPrefix(e, "PWD=") {
-					// PWD is usually absolute path.
-					// if cwd agnostic, then we should remove
-					// PWD environment variable.
-					continue
+			err = cwdAgnosticReq(ctx, cmdConfig, r.filepath, r.gomaReq.Arg, r.gomaReq.Env)
+			if err != nil {
+				logger.Infof("non cwd agnostic: %v", err)
+				d = digest.Bytes("wrapper-script", []byte(wrapperScript))
+				envs = append(envs, fmt.Sprintf("INPUT_ROOT_DIR=%s", r.tree.RootDir()))
+				envs = append(envs, r.gomaReq.Env...)
+				r.addPlatformProperty(ctx, "dockerSiblingContainers", "true")
+			} else {
+				logger.Infof("cwd agnostic")
+				d = digest.Bytes("cwd-agnostic-wrapper-script", []byte(cwdAgnosticWrapperScript))
+				for _, e := range r.gomaReq.Env {
+					if strings.HasPrefix(e, "PWD=") {
+						// PWD is usually absolute path.
+						// if cwd agnostic, then we should remove
+						// PWD environment variable.
+						continue
+					}
+					envs = append(envs, e)
 				}
-				envs = append(envs, e)
 			}
 		}
 		wrappers = []wrapperDesc{
@@ -883,11 +978,11 @@
 	if !ok {
 		return "", fmt.Errorf("not found for %s", d)
 	}
-	gis, ok := src.(gomaInputSource)
+	idd, ok := src.(inputDigestData)
 	if !ok {
 		return "", fmt.Errorf("not input file for %s", d)
 	}
-	return gis.filename, nil
+	return idd.filename, nil
 }
 
 type byInputFilenames struct {
diff --git a/remoteexec/exec_test.go b/remoteexec/exec_test.go
index 7561e00..2e144b9 100644
--- a/remoteexec/exec_test.go
+++ b/remoteexec/exec_test.go
@@ -14,15 +14,15 @@
 
 func TestSortMissing(t *testing.T) {
 	inputs := []*gomapb.ExecReq_Input{
-		&gomapb.ExecReq_Input{
+		{
 			Filename: proto.String("../src/hello.cc"),
 			HashKey:  proto.String("hash-hello.cc"),
 		},
-		&gomapb.ExecReq_Input{
+		{
 			Filename: proto.String("../include/base.h"),
 			HashKey:  proto.String("hash-base.h"),
 		},
-		&gomapb.ExecReq_Input{
+		{
 			Filename: proto.String("../include/hello.h"),
 			HashKey:  proto.String("hash-hello.h"),
 		},
diff --git a/remoteexec/fake_cluster_for_test.go b/remoteexec/fake_cluster_for_test.go
index fa7803e..613d6b7 100644
--- a/remoteexec/fake_cluster_for_test.go
+++ b/remoteexec/fake_cluster_for_test.go
@@ -16,7 +16,6 @@
 	"time"
 
 	rpb "github.com/bazelbuild/remote-apis/build/bazel/remote/execution/v2"
-
 	"github.com/golang/protobuf/proto"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
@@ -231,7 +230,7 @@
 	libFindBadConstructs := f.newFileSpec("lib/libFindBadConstructs.so", false)
 	return &fakeToolchain{
 		descs: []*cpb.CmdDescriptor{
-			&cpb.CmdDescriptor{
+			{
 				Selector: &cpb.Selector{
 					Name:       "clang",
 					Version:    version,
@@ -243,7 +242,7 @@
 					PathType: cpb.CmdDescriptor_POSIX,
 				},
 			},
-			&cpb.CmdDescriptor{
+			{
 				Selector: &cpb.Selector{
 					Name:       "clang++",
 					Version:    version,
@@ -255,7 +254,7 @@
 					PathType: cpb.CmdDescriptor_POSIX,
 				},
 			},
-			&cpb.CmdDescriptor{
+			{
 				Selector: &cpb.Selector{
 					Name:       "libFindBadConstructs.so",
 					BinaryHash: libFindBadConstructs.Hash,
@@ -268,7 +267,7 @@
 		},
 		RemoteexecPlatform: &cpb.RemoteexecPlatform{
 			Properties: []*cpb.RemoteexecPlatform_Property{
-				&cpb.RemoteexecPlatform_Property{
+				{
 					Name:  "container-image",
 					Value: "docker://grpc.io/goma-dev/container-image@sha256:xxxx",
 				},
@@ -303,10 +302,10 @@
 	}
 
 	config.Configs = []*cpb.Config{
-		&cpb.Config{
+		{
 			RemoteexecPlatform: &cpb.RemoteexecPlatform{
 				Properties: []*cpb.RemoteexecPlatform_Property{
-					&cpb.RemoteexecPlatform_Property{
+					{
 						Name:  "container-image",
 						Value: containerImage,
 					},
@@ -346,6 +345,11 @@
 	f.m[fname] = string(buf)
 }
 
+// Dup dups oldname as newname.
+func (f *fakeLocalFiles) Dup(oldname, newname string) {
+	f.m[newname] = f.m[oldname]
+}
+
 // Open opens fake file.
 func (f *fakeLocalFiles) Open(fname string) (io.Reader, error) {
 	data, ok := f.m[fname]
diff --git a/remoteexec/fake_rbe_for_test.go b/remoteexec/fake_rbe_for_test.go
index af95f4a..4450a7c 100644
--- a/remoteexec/fake_rbe_for_test.go
+++ b/remoteexec/fake_rbe_for_test.go
@@ -17,7 +17,6 @@
 
 	rpb "github.com/bazelbuild/remote-apis/build/bazel/remote/execution/v2"
 	sempb "github.com/bazelbuild/remote-apis/build/bazel/semver"
-
 	"github.com/golang/protobuf/proto"
 	"github.com/golang/protobuf/ptypes"
 	"github.com/google/uuid"
diff --git a/remoteexec/fake_rbe_test.go b/remoteexec/fake_rbe_test.go
index 325a621..083bf7a 100644
--- a/remoteexec/fake_rbe_test.go
+++ b/remoteexec/fake_rbe_test.go
@@ -311,7 +311,7 @@
 		return err
 	}
 
-	if !cmp.Equal(dbuf.Bytes(), buf.Bytes()) {
+	if !bytes.Equal(dbuf.Bytes(), buf.Bytes()) {
 		return fmt.Errorf("digest content mismatch for %s", resname)
 	}
 	return nil
diff --git a/remoteexec/gomainput.go b/remoteexec/gomainput.go
index f370554..21f4b07 100644
--- a/remoteexec/gomainput.go
+++ b/remoteexec/gomainput.go
@@ -52,7 +52,6 @@
 	src := gomaInputSource{
 		lookupClient: gi.gomaFile,
 		hashKey:      hashKey,
-		filename:     input.GetFilename(),
 		blob:         input.GetContent(),
 	}
 	return gi.digestCache.Get(ctx, hashKey, src)
@@ -103,12 +102,11 @@
 type gomaInputSource struct {
 	lookupClient lookupClient
 	hashKey      string
-	filename     string
 	blob         *gomapb.FileBlob
 }
 
 func (g gomaInputSource) String() string {
-	return fmt.Sprintf("goma-input:%s %p %s", g.hashKey, g.blob, g.filename)
+	return fmt.Sprintf("goma-input:%s %p", g.hashKey, g.blob)
 }
 
 func (g gomaInputSource) Open(ctx context.Context) (io.ReadCloser, error) {
diff --git a/remoteexec/gomaoutput.go b/remoteexec/gomaoutput.go
index cd177b9..58d34ea 100644
--- a/remoteexec/gomaoutput.go
+++ b/remoteexec/gomaoutput.go
@@ -168,7 +168,7 @@
 		err = rpc.Retry{}.Do(ctx, func() error {
 			resp, err = g.gomaFile.StoreFile(ctx, &gomapb.StoreFileReq{
 				Blob: []*gomapb.FileBlob{
-					&gomapb.FileBlob{
+					{
 						BlobType: gomapb.FileBlob_FILE_CHUNK.Enum(),
 						Offset:   proto.Int64(offset),
 						Content:  buf[:n],
diff --git a/remoteexec/inputroot.go b/remoteexec/inputroot.go
index 1130fc4..33e657a 100644
--- a/remoteexec/inputroot.go
+++ b/remoteexec/inputroot.go
@@ -96,9 +96,9 @@
 	return true
 }
 
-// needOverlay returns true if overlayfs is needed to run the task with
+// needChroot returns true if chroot is needed to run the task with
 // given common `dir`
-func needOverlay(filepath clientFilePath, dir string) bool {
+func needChroot(filepath clientFilePath, dir string) bool {
 	return !validCommonDir(filepath, dir)
 }
 
@@ -150,18 +150,14 @@
 }
 
 // inputRootDir returns common root of paths.
-// If second return value is true, overlayfs must be used.  It become true only
-// if `allowOverlay` is true and common input root is "/".
-func inputRootDir(filepath clientFilePath, paths []string, allowOverlay bool) (string, bool, error) {
+// If second return value is true, chroot must be used.  It become true only
+// if `allowChroot` is true and common input root is "/".
+func inputRootDir(filepath clientFilePath, paths []string, allowChroot bool) (string, bool, error) {
 	root := commonDir(filepath, paths)
-	if needOverlay(filepath, root) && allowOverlay {
+	if needChroot(filepath, root) && allowChroot {
 		switch filepath.(type) {
 		// TODO: support non-posix platform
 		case posixpath.FilePath:
-			err := verifyPathsForOverlay(paths)
-			if err != nil {
-				return "", false, err
-			}
 			return "/", true, nil
 		}
 	}
@@ -223,28 +219,3 @@
 	}
 	return p[len(prefix)] == '/'
 }
-
-// verifyPathsForOverlay verifies paths won't overwrite files including libs
-// used by docker or internal work directory.
-// It returns nil for success, and error for failure.
-// TODO: support non-posix platforms.
-func verifyPathsForOverlay(paths []string) error {
-	blacklist := []string{
-		// for docker
-		"/bin",
-		"/sbin",
-		"/lib",
-		"/lib64",
-		"/dev",
-		// for internal work directory.
-		"/workdir",
-	}
-	for _, p := range paths {
-		for _, b := range blacklist {
-			if hasPrefixDir(p, b) {
-				return fmt.Errorf("%s contains blacklisted dir: %s", p, b)
-			}
-		}
-	}
-	return nil
-}
diff --git a/remoteexec/inputroot_test.go b/remoteexec/inputroot_test.go
index 9821526..f598010 100644
--- a/remoteexec/inputroot_test.go
+++ b/remoteexec/inputroot_test.go
@@ -90,27 +90,27 @@
 
 func TestInputRootDir(t *testing.T) {
 	for _, tc := range []struct {
-		desc         string
-		req          *gomapb.ExecReq
-		argv0        string
-		allowOverlay bool
-		want         string
-		wantOverlay  bool
-		wantPathErr  bool
-		wantRootErr  bool
+		desc        string
+		req         *gomapb.ExecReq
+		argv0       string
+		allowChroot bool
+		want        string
+		wantChroot  bool
+		wantPathErr bool
+		wantRootErr bool
 	}{
 		{
 			desc: "basic",
 			req: &gomapb.ExecReq{
 				Cwd: proto.String("/b/c/b/linux/src/out/Release"),
 				Input: []*gomapb.ExecReq_Input{
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("../../base/logging.h"),
 					},
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("../../build/linux/debian_sid_amd64-sysroot/usr/include/stdio.h"),
 					},
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("gen/chrome/common/buildflags.h"),
 					},
 				},
@@ -123,13 +123,13 @@
 			req: &gomapb.ExecReq{
 				Cwd: proto.String("/b/c/b/linux/src/out/Release"),
 				Input: []*gomapb.ExecReq_Input{
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("/b/c/b/linux/src/out/Release/../../base/logging.h"),
 					},
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("/b/c/b/linux/src/out/Release/../../build/linux/debian_sid_amd64-sysroot/usr/include/stdio.h"),
 					},
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("/b/c/b/linux/src/out/Release/gen/chrome/common/buildflags.h"),
 					},
 				},
@@ -142,13 +142,13 @@
 			req: &gomapb.ExecReq{
 				Cwd: proto.String("/b/c/b/linux/src/out/Release"),
 				Input: []*gomapb.ExecReq_Input{
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("/b/c/b/linux/src/base/logging.h"),
 					},
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("/b/c/b/linux/src/build/linux/debian_sid_amd64-sysroot/usr/include/stdio.h"),
 					},
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("/b/c/b/linux/src/out/Release/gen/chrome/common/buildflags.h"),
 					},
 				},
@@ -161,16 +161,16 @@
 			req: &gomapb.ExecReq{
 				Cwd: proto.String("/b/c/b/linux/src/out/Release"),
 				Input: []*gomapb.ExecReq_Input{
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("../../base/logging.h"),
 					},
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("../../build/linux/debian_sid_amd64-sysroot/usr/include/stdio.h"),
 					},
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("gen/chrome/common/buildflags.h"),
 					},
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("/usr/local/include/foo.h"),
 					},
 				},
@@ -183,13 +183,13 @@
 			req: &gomapb.ExecReq{
 				Cwd: proto.String("b/c/b/linux/src/out/Release"),
 				Input: []*gomapb.ExecReq_Input{
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("../../base/logging.h"),
 					},
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("../../build/linux/debian_sid_amd64-sysroot/usr/include/stdio.h"),
 					},
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("gen/chrome/common/buildflags.h"),
 					},
 				},
@@ -202,10 +202,10 @@
 			req: &gomapb.ExecReq{
 				Cwd: proto.String("/b/c/b/linux/src/out/Release"),
 				Input: []*gomapb.ExecReq_Input{
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("gen/chrome/common/buildflags.h"),
 					},
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("gen/chrome/common/buildflags.cc"),
 					},
 				},
@@ -218,10 +218,10 @@
 			req: &gomapb.ExecReq{
 				Cwd: proto.String("/b/c/b/linux/src/out/Release"),
 				Input: []*gomapb.ExecReq_Input{
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("gen/chrome/common/buildflags.h"),
 					},
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("gen/chrome/common/buildflags.cc"),
 					},
 				},
@@ -234,16 +234,16 @@
 			req: &gomapb.ExecReq{
 				Cwd: proto.String("/usr/home/foo/src/out/Release"),
 				Input: []*gomapb.ExecReq_Input{
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("../../base/logging.h"),
 					},
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("../../build/linux/debian_sid_amd64-sysroot/usr/include/stdio.h"),
 					},
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("gen/chrome/common/buildflags.h"),
 					},
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("/usr/lib/gcc/x86_64-linux-gnu/7/crtbegin.o"),
 					},
 				},
@@ -252,19 +252,19 @@
 			wantRootErr: true,
 		},
 		{
-			desc: "wantOverlay for /usr",
+			desc: "wantChroot for /usr",
 			req: &gomapb.ExecReq{
 				Cwd: proto.String("/home/foo/src/out/Release"),
 				Input: []*gomapb.ExecReq_Input{
-					&gomapb.ExecReq_Input{
+					{
 						Filename: proto.String("/usr/include/config.h"),
 					},
 				},
 			},
-			argv0:        "../../third_party/llvm-build/Release+Asserts/bin/clang++",
-			want:         "/",
-			allowOverlay: true,
-			wantOverlay:  true,
+			argv0:       "../../third_party/llvm-build/Release+Asserts/bin/clang++",
+			want:        "/",
+			allowChroot: true,
+			wantChroot:  true,
 		},
 	} {
 		t.Logf("test case: %s", tc.desc)
@@ -278,15 +278,15 @@
 		if err != nil {
 			t.Errorf("inputPaths(req, %q)=%v, %v; want nil error", tc.argv0, paths, err)
 		}
-		got, overlay, err := inputRootDir(posixpath.FilePath{}, paths, tc.allowOverlay)
+		got, needChroot, err := inputRootDir(posixpath.FilePath{}, paths, tc.allowChroot)
 		if tc.wantRootErr {
 			if err == nil {
-				t.Errorf("inputRootDir(files)=%v, %t, nil; want err", got, overlay)
+				t.Errorf("inputRootDir(files)=%v, %t, nil; want err", got, needChroot)
 			}
 			continue
 		}
-		if err != nil || got != tc.want || overlay != tc.wantOverlay {
-			t.Errorf("inputRootDir(files)=%v, %t, %v; want %v, %t, nil", got, overlay, err, tc.want, tc.wantOverlay)
+		if err != nil || got != tc.want || needChroot != tc.wantChroot {
+			t.Errorf("inputRootDir(files)=%v, %t, %v; want %v, %t, nil", got, needChroot, err, tc.want, tc.wantChroot)
 		}
 	}
 }
@@ -434,52 +434,3 @@
 		}
 	}
 }
-
-func TestVerifyPathsForOverlay(t *testing.T) {
-	for _, tc := range []struct {
-		paths     []string
-		wantError bool
-	}{
-		{
-			paths:     []string{"/home/foo/"},
-			wantError: false,
-		},
-		{
-			paths:     []string{"/bin/sh"},
-			wantError: true,
-		},
-		{
-			paths:     []string{"/sbin/shutdown"},
-			wantError: true,
-		},
-		{
-			paths:     []string{"/lib/libc.so.6"},
-			wantError: true,
-		},
-		{
-			paths:     []string{"/lib64/ld-linux-x86-64.so.2"},
-			wantError: true,
-		},
-		{
-			paths:     []string{"/dev/urandom"},
-			wantError: true,
-		},
-		{
-			paths:     []string{"/workdir"},
-			wantError: true,
-		},
-		// has non-blacklist and blacklist.
-		{
-			paths:     []string{"/home", "/workdir"},
-			wantError: true,
-		},
-	} {
-		err := verifyPathsForOverlay(tc.paths)
-		if err == nil && tc.wantError {
-			t.Errorf("verifyPathsForOverlay(%q) = nil; want error", tc.paths)
-		}
-		if err != nil && !tc.wantError {
-			t.Errorf("verifyPathsForOverlay(%q) = %v; want nil", tc.paths, err)
-		}
-	}
-}
diff --git a/remoteexec/merkletree/merkletree_test.go b/remoteexec/merkletree/merkletree_test.go
index 0dde61a..99d7041 100644
--- a/remoteexec/merkletree/merkletree_test.go
+++ b/remoteexec/merkletree/merkletree_test.go
@@ -286,13 +286,13 @@
 	mt := New(posixpath.FilePath{}, "/path/to/root", ds)
 
 	for _, ent := range []Entry{
-		Entry{
+		{
 			// Invalid Entry: Absolute path.
 			Name:         "/usr/bin/third_party/llvm-build/Release+Asserts/bin/clang",
 			Data:         digest.Bytes("clang binary", []byte("clang binary")),
 			IsExecutable: true,
 		},
-		Entry{
+		{
 			// Invalid Entry: has both `Data` and `Target` fields set.
 			Name:   "third_party/llvm-build/Release+Asserts/bin/clang++",
 			Data:   digest.Bytes("clang binary", []byte("clang binary")),
@@ -312,41 +312,41 @@
 	mt := New(posixpath.FilePath{}, "/path/to/root", ds)
 
 	for _, ent := range []Entry{
-		Entry{
+		{
 			Name:         "third_party/llvm-build/Release+Asserts/bin/clang",
 			Data:         digest.Bytes("clang binary", []byte("clang binary")),
 			IsExecutable: true,
 		},
-		Entry{
+		{
 			Name:   "third_party/llvm-build/Release+Asserts/bin/clang++-1",
 			Target: "clang",
 		},
-		Entry{
+		{
 			Name:   "third_party/llvm-build/Release+Asserts/bin/clang++",
 			Target: "clang",
 		},
-		Entry{
+		{
 			Name: "base/build_time.h",
 			Data: digest.Bytes("base_time.h", []byte("byte_time.h content")),
 		},
-		Entry{
+		{
 			Name: "out/Release/obj/base",
 			// directory
 		},
-		Entry{
+		{
 			Name: "base/debug/debugger.cc",
 			Data: digest.Bytes("debugger.cc", []byte("debugger.cc content")),
 		},
-		Entry{
+		{
 			Name: "base/test/../macros.h",
 			Data: digest.Bytes("macros.h", []byte("macros.h content")),
 		},
 		// de-dup for same content http://b/124693412
-		Entry{
+		{
 			Name: "third_party/skia/include/private/SkSafe32.h",
 			Data: digest.Bytes("SkSafe32.h", []byte("SkSafe32.h content")),
 		},
-		Entry{
+		{
 			Name: "third_party/skia/include/private/SkSafe32.h",
 			Data: digest.Bytes("SkSafe32.h", []byte("SkSafe32.h content")),
 		},
@@ -422,11 +422,11 @@
 		{
 			desc: "dup file-file",
 			ents: []Entry{
-				Entry{
+				{
 					Name: "dir/file1",
 					Data: digest.Bytes("file1.1", []byte("file1.1")),
 				},
-				Entry{
+				{
 					Name: "dir/file1",
 					Data: digest.Bytes("file1.2", []byte("file1.2")),
 				},
@@ -435,11 +435,11 @@
 		{
 			desc: "dup file-symlink",
 			ents: []Entry{
-				Entry{
+				{
 					Name: "dir/foo",
 					Data: digest.Bytes("foo file", []byte("foo file")),
 				},
-				Entry{
+				{
 					Name:   "dir/foo",
 					Target: "bar",
 				},
@@ -448,11 +448,11 @@
 		{
 			desc: "dup file-dir",
 			ents: []Entry{
-				Entry{
+				{
 					Name: "dir/foo",
 					Data: digest.Bytes("foo file", []byte("foo file")),
 				},
-				Entry{
+				{
 					Name: "dir/foo",
 				},
 			},
@@ -460,11 +460,11 @@
 		{
 			desc: "dup symlink-dir",
 			ents: []Entry{
-				Entry{
+				{
 					Name:   "dir/foo",
 					Target: "bar",
 				},
-				Entry{
+				{
 					Name: "dir/foo",
 				},
 			},