func DefaultExecutionOptions() *ExecutionOptions {
	return &ExecutionOptions{
		AcceptCached:    true,
		DoNotCache:      false,
		DownloadOutputs: true,
		DownloadOutErr:  true,
	}
}
DefaultExecutionOptions returns the recommended ExecutionOptions.
package command
import (
	"crypto/sha256"
	"encoding/hex"
	"errors"
	"fmt"
	"sort"
	"time"
	"github.com/bazelbuild/remote-apis-sdks/go/pkg/digest"
	"github.com/golang/protobuf/ptypes"
	"github.com/pborman/uuid"
	cpb "github.com/bazelbuild/remote-apis-sdks/go/api/command"
	repb "github.com/bazelbuild/remote-apis/build/bazel/remote/execution/v2"
	log "github.com/golang/glog"
	tspb "github.com/golang/protobuf/ptypes/timestamp"
)
type InputType int
const (
	UnspecifiedInputType InputType = iota
	DirectoryInputType
	FileInputType
	SymlinkInputType
)
var inputTypes = [...]string{"UnspecifiedInputType", "DirectoryInputType", "FileInputType"}
func (s InputType) String() string {
	if UnspecifiedInputType <= s && s <= FileInputType {
		return inputTypes[s]
	}
	return fmt.Sprintf("InvalidInputType(%d)", s)
}
type SymlinkBehaviorType int
const (
	UnspecifiedSymlinkBehavior SymlinkBehaviorType = iota
	ResolveSymlink
	PreserveSymlink
)
var symlinkBehaviorType = [...]string{"UnspecifiedSymlinkBehavior", "ResolveSymlink", "PreserveSymlink"}
func (s SymlinkBehaviorType) String() string {
	if UnspecifiedSymlinkBehavior <= s && s <= PreserveSymlink {
		return symlinkBehaviorType[s-UnspecifiedSymlinkBehavior]
	}
	return fmt.Sprintf("InvalidSymlinkBehaviorType(%d)", s)
}
type InputExclusion struct {
	Regex string
	Type InputType
}
type VirtualInput struct {
	Path string
	Contents []byte
	IsExecutable bool
	IsEmptyDirectory bool
}
type InputSpec struct {
	Inputs []string
	VirtualInputs []*VirtualInput
	InputExclusions []*InputExclusion
	EnvironmentVariables map[string]string
	SymlinkBehavior SymlinkBehaviorType
}
func (s *VirtualInput) String() string {
	return fmt.Sprintf("%+v", *s)
}
func (s *InputExclusion) String() string {
	return fmt.Sprintf("%+v", *s)
}
type Identifiers struct {
	CommandID string
	InvocationID string
	CorrelatedInvocationID string
	ToolName string
	ToolVersion string
	ExecutionID string
}
type Command struct {
	Identifiers *Identifiers
	Args []string
	ExecRoot string
	WorkingDir string
	InputSpec *InputSpec
	OutputFiles []string
	OutputDirs []string
	Timeout time.Duration
	Platform map[string]string
}
func marshallMap(m map[string]string, buf *[]byte) {
	var pkeys []string
	for k := range m {
		pkeys = append(pkeys, k)
	}
	sort.Strings(pkeys)
	for _, k := range pkeys {
		*buf = append(*buf, []byte(k)...)
		*buf = append(*buf, []byte(m[k])...)
	}
}
func marshallSlice(s []string, buf *[]byte) {
	for _, i := range s {
		*buf = append(*buf, []byte(i)...)
	}
}
func marshallSortedSlice(s []string, buf *[]byte) {
	ss := make([]string, len(s))
	copy(ss, s)
	sort.Strings(ss)
	marshallSlice(ss, buf)
}
func (c *Command) Validate() error {
	if c == nil {
		return nil
	}
	if len(c.Args) == 0 {
		return errors.New("missing command arguments")
	}
	if c.ExecRoot == "" {
		return errors.New("missing command exec root")
	}
	if c.InputSpec == nil {
		return errors.New("missing command input spec")
	}
	if c.Identifiers == nil {
		return errors.New("missing command identifiers")
	}
	return nil
}
func (c *Command) stableID() string {
	var buf []byte
	marshallSlice(c.Args, &buf)
	buf = append(buf, []byte(c.ExecRoot)...)
	buf = append(buf, []byte(c.WorkingDir)...)
	marshallSortedSlice(c.OutputFiles, &buf)
	marshallSortedSlice(c.OutputDirs, &buf)
	buf = append(buf, []byte(c.Timeout.String())...)
	marshallMap(c.Platform, &buf)
	if c.InputSpec != nil {
		marshallMap(c.InputSpec.EnvironmentVariables, &buf)
		marshallSortedSlice(c.InputSpec.Inputs, &buf)
		inputExclusions := make([]*InputExclusion, len(c.InputSpec.InputExclusions))
		copy(inputExclusions, c.InputSpec.InputExclusions)
		sort.Slice(inputExclusions, func(i, j int) bool {
			e1 := inputExclusions[i]
			e2 := inputExclusions[j]
			return e1.Regex > e2.Regex || e1.Regex == e2.Regex && e1.Type > e2.Type
		})
		for _, e := range inputExclusions {
			buf = append(buf, []byte(e.Regex)...)
			buf = append(buf, []byte(e.Type.String())...)
		}
	}
	sha256Arr := sha256.Sum256(buf)
	return hex.EncodeToString(sha256Arr[:])[:8]
}
func (c *Command) FillDefaultFieldValues() {
	if c == nil {
		return
	}
	if c.Identifiers == nil {
		c.Identifiers = &Identifiers{}
	}
	if c.Identifiers.CommandID == "" {
		c.Identifiers.CommandID = c.stableID()
	}
	if c.Identifiers.ToolName == "" {
		c.Identifiers.ToolName = "remote-client"
	}
	if c.Identifiers.InvocationID == "" {
		c.Identifiers.InvocationID = uuid.New()
	}
	if c.Identifiers.ExecutionID == "" {
		c.Identifiers.ExecutionID = uuid.New()
	}
	if c.InputSpec == nil {
		c.InputSpec = &InputSpec{}
	}
}
type ExecutionOptions struct {
	AcceptCached bool
	DoNotCache bool
	DownloadOutputs bool
	DownloadOutErr bool
}