// Code generated by protoc-gen-go. DO NOT EDIT.
// source: relui.proto

package protos

import (
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

type TaskStatus int32

const (
	TaskStatus_TASK_STATUS_UNKNOWN TaskStatus = 0
	TaskStatus_TASK_STATUS_CREATED TaskStatus = 1
	TaskStatus_TASK_STATUS_STARTED TaskStatus = 2
)

var TaskStatus_name = map[int32]string{
	0: "TASK_STATUS_UNKNOWN",
	1: "TASK_STATUS_CREATED",
	2: "TASK_STATUS_STARTED",
}

var TaskStatus_value = map[string]int32{
	"TASK_STATUS_UNKNOWN": 0,
	"TASK_STATUS_CREATED": 1,
	"TASK_STATUS_STARTED": 2,
}

func (x TaskStatus) String() string {
	return proto.EnumName(TaskStatus_name, int32(x))
}

func (TaskStatus) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_6de8859f82adce0a, []int{0}
}

type Workflow struct {
	// name is a unique name for a workflow, such as local_go_release. The name must be unique across
	// all workflow configurations.
	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	// buildable_asks is a list of tasks to be performed by the workflow.
	BuildableTasks []*BuildableTask `protobuf:"bytes,2,rep,name=buildable_tasks,json=buildableTasks,proto3" json:"buildable_tasks,omitempty"`
	// params are parameters provided when creating a workflow.
	Params map[string]string `protobuf:"bytes,3,rep,name=params,proto3" json:"params,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
	// id is a unique identifier generated by relui when a workflow is created.
	Id                   string   `protobuf:"bytes,4,opt,name=id,proto3" json:"id,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *Workflow) Reset()         { *m = Workflow{} }
func (m *Workflow) String() string { return proto.CompactTextString(m) }
func (*Workflow) ProtoMessage()    {}
func (*Workflow) Descriptor() ([]byte, []int) {
	return fileDescriptor_6de8859f82adce0a, []int{0}
}

func (m *Workflow) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_Workflow.Unmarshal(m, b)
}
func (m *Workflow) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_Workflow.Marshal(b, m, deterministic)
}
func (m *Workflow) XXX_Merge(src proto.Message) {
	xxx_messageInfo_Workflow.Merge(m, src)
}
func (m *Workflow) XXX_Size() int {
	return xxx_messageInfo_Workflow.Size(m)
}
func (m *Workflow) XXX_DiscardUnknown() {
	xxx_messageInfo_Workflow.DiscardUnknown(m)
}

var xxx_messageInfo_Workflow proto.InternalMessageInfo

func (m *Workflow) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

func (m *Workflow) GetBuildableTasks() []*BuildableTask {
	if m != nil {
		return m.BuildableTasks
	}
	return nil
}

func (m *Workflow) GetParams() map[string]string {
	if m != nil {
		return m.Params
	}
	return nil
}

func (m *Workflow) GetId() string {
	if m != nil {
		return m.Id
	}
	return ""
}

type BuildableTask struct {
	// name is a unique name for a task, such as fetch_go_source. The name must be unique across
	// all workflow configurations.
	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	// depends_on is the name of a task this task depends on. Artifacts from the depends_on task will be available
	// to this task.
	DependsOn string `protobuf:"bytes,2,opt,name=depends_on,json=dependsOn,proto3" json:"depends_on,omitempty"`
	// task_status is the current status of a task.
	Status TaskStatus `protobuf:"varint,3,opt,name=status,proto3,enum=protos.TaskStatus" json:"status,omitempty"`
	// artifact_url is an optional URL to an artifact published by this task.
	ArtifactUrl string `protobuf:"bytes,4,opt,name=artifact_url,json=artifactUrl,proto3" json:"artifact_url,omitempty"`
	// git_source is an optional configuration for which git source to fetch.
	GitSource *GitSource `protobuf:"bytes,5,opt,name=git_source,json=gitSource,proto3" json:"git_source,omitempty"`
	// task_type is a unique type for a task, such as FetchGerritSource. Types are used by task runners to identify
	// how to execute a task.
	TaskType string `protobuf:"bytes,6,opt,name=task_type,json=taskType,proto3" json:"task_type,omitempty"`
	// id is a unique identifier generated by relui when a buildable task is created.
	Id                   string   `protobuf:"bytes,7,opt,name=id,proto3" json:"id,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *BuildableTask) Reset()         { *m = BuildableTask{} }
func (m *BuildableTask) String() string { return proto.CompactTextString(m) }
func (*BuildableTask) ProtoMessage()    {}
func (*BuildableTask) Descriptor() ([]byte, []int) {
	return fileDescriptor_6de8859f82adce0a, []int{1}
}

func (m *BuildableTask) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_BuildableTask.Unmarshal(m, b)
}
func (m *BuildableTask) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_BuildableTask.Marshal(b, m, deterministic)
}
func (m *BuildableTask) XXX_Merge(src proto.Message) {
	xxx_messageInfo_BuildableTask.Merge(m, src)
}
func (m *BuildableTask) XXX_Size() int {
	return xxx_messageInfo_BuildableTask.Size(m)
}
func (m *BuildableTask) XXX_DiscardUnknown() {
	xxx_messageInfo_BuildableTask.DiscardUnknown(m)
}

var xxx_messageInfo_BuildableTask proto.InternalMessageInfo

func (m *BuildableTask) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

func (m *BuildableTask) GetDependsOn() string {
	if m != nil {
		return m.DependsOn
	}
	return ""
}

func (m *BuildableTask) GetStatus() TaskStatus {
	if m != nil {
		return m.Status
	}
	return TaskStatus_TASK_STATUS_UNKNOWN
}

func (m *BuildableTask) GetArtifactUrl() string {
	if m != nil {
		return m.ArtifactUrl
	}
	return ""
}

func (m *BuildableTask) GetGitSource() *GitSource {
	if m != nil {
		return m.GitSource
	}
	return nil
}

func (m *BuildableTask) GetTaskType() string {
	if m != nil {
		return m.TaskType
	}
	return ""
}

func (m *BuildableTask) GetId() string {
	if m != nil {
		return m.Id
	}
	return ""
}

// StartBuildableTaskRequest is a message sent to workers to start working on a BuildableTask for a Workflow.
type StartBuildableTaskRequest struct {
	// workflow_id is the workflow to which the BuildableTask belongs.
	WorkflowId string `protobuf:"bytes,1,opt,name=workflow_id,json=workflowId,proto3" json:"workflow_id,omitempty"`
	// buildable_task_id is the id of the BuildableTask to be started.
	BuildableTaskId string `protobuf:"bytes,2,opt,name=buildable_task_id,json=buildableTaskId,proto3" json:"buildable_task_id,omitempty"`
	// buildable_task_type is the type of the BuildableTask to be started.
	BuildableTaskType    string   `protobuf:"bytes,3,opt,name=buildable_task_type,json=buildableTaskType,proto3" json:"buildable_task_type,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *StartBuildableTaskRequest) Reset()         { *m = StartBuildableTaskRequest{} }
func (m *StartBuildableTaskRequest) String() string { return proto.CompactTextString(m) }
func (*StartBuildableTaskRequest) ProtoMessage()    {}
func (*StartBuildableTaskRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_6de8859f82adce0a, []int{2}
}

func (m *StartBuildableTaskRequest) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_StartBuildableTaskRequest.Unmarshal(m, b)
}
func (m *StartBuildableTaskRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_StartBuildableTaskRequest.Marshal(b, m, deterministic)
}
func (m *StartBuildableTaskRequest) XXX_Merge(src proto.Message) {
	xxx_messageInfo_StartBuildableTaskRequest.Merge(m, src)
}
func (m *StartBuildableTaskRequest) XXX_Size() int {
	return xxx_messageInfo_StartBuildableTaskRequest.Size(m)
}
func (m *StartBuildableTaskRequest) XXX_DiscardUnknown() {
	xxx_messageInfo_StartBuildableTaskRequest.DiscardUnknown(m)
}

var xxx_messageInfo_StartBuildableTaskRequest proto.InternalMessageInfo

func (m *StartBuildableTaskRequest) GetWorkflowId() string {
	if m != nil {
		return m.WorkflowId
	}
	return ""
}

func (m *StartBuildableTaskRequest) GetBuildableTaskId() string {
	if m != nil {
		return m.BuildableTaskId
	}
	return ""
}

func (m *StartBuildableTaskRequest) GetBuildableTaskType() string {
	if m != nil {
		return m.BuildableTaskType
	}
	return ""
}

// LocalStorage is the persisted data of relui. It is used in development mode for saving application state.
type LocalStorage struct {
	// workflows are a list of user-created workflows.
	Workflows            []*Workflow `protobuf:"bytes,1,rep,name=workflows,proto3" json:"workflows,omitempty"`
	XXX_NoUnkeyedLiteral struct{}    `json:"-"`
	XXX_unrecognized     []byte      `json:"-"`
	XXX_sizecache        int32       `json:"-"`
}

func (m *LocalStorage) Reset()         { *m = LocalStorage{} }
func (m *LocalStorage) String() string { return proto.CompactTextString(m) }
func (*LocalStorage) ProtoMessage()    {}
func (*LocalStorage) Descriptor() ([]byte, []int) {
	return fileDescriptor_6de8859f82adce0a, []int{3}
}

func (m *LocalStorage) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_LocalStorage.Unmarshal(m, b)
}
func (m *LocalStorage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_LocalStorage.Marshal(b, m, deterministic)
}
func (m *LocalStorage) XXX_Merge(src proto.Message) {
	xxx_messageInfo_LocalStorage.Merge(m, src)
}
func (m *LocalStorage) XXX_Size() int {
	return xxx_messageInfo_LocalStorage.Size(m)
}
func (m *LocalStorage) XXX_DiscardUnknown() {
	xxx_messageInfo_LocalStorage.DiscardUnknown(m)
}

var xxx_messageInfo_LocalStorage proto.InternalMessageInfo

func (m *LocalStorage) GetWorkflows() []*Workflow {
	if m != nil {
		return m.Workflows
	}
	return nil
}

type GitSource struct {
	Url                  string   `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"`
	Ref                  string   `protobuf:"bytes,2,opt,name=ref,proto3" json:"ref,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *GitSource) Reset()         { *m = GitSource{} }
func (m *GitSource) String() string { return proto.CompactTextString(m) }
func (*GitSource) ProtoMessage()    {}
func (*GitSource) Descriptor() ([]byte, []int) {
	return fileDescriptor_6de8859f82adce0a, []int{4}
}

func (m *GitSource) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_GitSource.Unmarshal(m, b)
}
func (m *GitSource) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_GitSource.Marshal(b, m, deterministic)
}
func (m *GitSource) XXX_Merge(src proto.Message) {
	xxx_messageInfo_GitSource.Merge(m, src)
}
func (m *GitSource) XXX_Size() int {
	return xxx_messageInfo_GitSource.Size(m)
}
func (m *GitSource) XXX_DiscardUnknown() {
	xxx_messageInfo_GitSource.DiscardUnknown(m)
}

var xxx_messageInfo_GitSource proto.InternalMessageInfo

func (m *GitSource) GetUrl() string {
	if m != nil {
		return m.Url
	}
	return ""
}

func (m *GitSource) GetRef() string {
	if m != nil {
		return m.Ref
	}
	return ""
}

func init() {
	proto.RegisterEnum("protos.TaskStatus", TaskStatus_name, TaskStatus_value)
	proto.RegisterType((*Workflow)(nil), "protos.Workflow")
	proto.RegisterMapType((map[string]string)(nil), "protos.Workflow.ParamsEntry")
	proto.RegisterType((*BuildableTask)(nil), "protos.BuildableTask")
	proto.RegisterType((*StartBuildableTaskRequest)(nil), "protos.StartBuildableTaskRequest")
	proto.RegisterType((*LocalStorage)(nil), "protos.LocalStorage")
	proto.RegisterType((*GitSource)(nil), "protos.GitSource")
}

func init() { proto.RegisterFile("relui.proto", fileDescriptor_6de8859f82adce0a) }

var fileDescriptor_6de8859f82adce0a = []byte{
	// 486 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x53, 0xdd, 0x6e, 0xd3, 0x30,
	0x14, 0xc6, 0xe9, 0x56, 0x96, 0x93, 0xd1, 0xb5, 0x1e, 0x88, 0xf0, 0x27, 0x4a, 0xae, 0xaa, 0x5e,
	0x04, 0x54, 0xb8, 0x00, 0x2e, 0x26, 0x15, 0xa8, 0xd0, 0x34, 0xd4, 0xa1, 0x24, 0x55, 0x2f, 0x23,
	0xb7, 0x71, 0xab, 0xa8, 0x5e, 0x12, 0x6c, 0x87, 0xa9, 0x6f, 0xc2, 0xdb, 0xf1, 0x0a, 0x3c, 0x02,
	0xb2, 0x6b, 0xb3, 0xa6, 0xe2, 0x2a, 0xc7, 0xe7, 0xfb, 0x7c, 0xfc, 0x9d, 0xef, 0x9c, 0x80, 0xc7,
	0x29, 0xab, 0xf3, 0xb0, 0xe2, 0xa5, 0x2c, 0x71, 0x5b, 0x7f, 0x44, 0xf0, 0x1b, 0xc1, 0xc9, 0xbc,
	0xe4, 0x9b, 0x15, 0x2b, 0x6f, 0x31, 0x86, 0xa3, 0x82, 0xdc, 0x50, 0x1f, 0xf5, 0xd1, 0xc0, 0x8d,
	0x74, 0x8c, 0x2f, 0xe0, 0x6c, 0x51, 0xe7, 0x2c, 0x23, 0x0b, 0x46, 0x53, 0x49, 0xc4, 0x46, 0xf8,
	0x4e, 0xbf, 0x35, 0xf0, 0x46, 0x8f, 0x76, 0x95, 0x44, 0xf8, 0xc9, 0xc2, 0x09, 0x11, 0x9b, 0xa8,
	0xb3, 0xd8, 0x3f, 0x0a, 0xfc, 0x0e, 0xda, 0x15, 0xe1, 0xe4, 0x46, 0xf8, 0x2d, 0x7d, 0xed, 0xb9,
	0xbd, 0x66, 0x5f, 0x0d, 0xbf, 0x6b, 0x78, 0x52, 0x48, 0xbe, 0x8d, 0x0c, 0x17, 0x77, 0xc0, 0xc9,
	0x33, 0xff, 0x48, 0xeb, 0x70, 0xf2, 0xec, 0xe9, 0x07, 0xf0, 0xf6, 0x68, 0xb8, 0x0b, 0xad, 0x0d,
	0xdd, 0x1a, 0x9d, 0x2a, 0xc4, 0x0f, 0xe1, 0xf8, 0x27, 0x61, 0x35, 0xf5, 0x1d, 0x9d, 0xdb, 0x1d,
	0x3e, 0x3a, 0xef, 0x51, 0xf0, 0x07, 0xc1, 0x83, 0x86, 0xc4, 0xff, 0xb6, 0xf9, 0x02, 0x20, 0xa3,
	0x15, 0x2d, 0x32, 0x91, 0x96, 0x85, 0x29, 0xe2, 0x9a, 0xcc, 0x75, 0x81, 0x87, 0xd0, 0x16, 0x92,
	0xc8, 0x5a, 0x75, 0x81, 0x06, 0x9d, 0x11, 0xb6, 0x5d, 0xa8, 0x82, 0xb1, 0x46, 0x22, 0xc3, 0xc0,
	0xaf, 0xe0, 0x94, 0x70, 0x99, 0xaf, 0xc8, 0x52, 0xa6, 0x35, 0x67, 0xa6, 0x0b, 0xcf, 0xe6, 0x66,
	0x9c, 0xe1, 0x37, 0x00, 0xeb, 0x5c, 0xa6, 0xa2, 0xac, 0xf9, 0x92, 0xfa, 0xc7, 0x7d, 0x34, 0xf0,
	0x46, 0x3d, 0x5b, 0xf2, 0x6b, 0x2e, 0x63, 0x0d, 0x44, 0xee, 0xda, 0x86, 0xf8, 0x19, 0xb8, 0xca,
	0xfc, 0x54, 0x6e, 0x2b, 0xea, 0xb7, 0x75, 0xc5, 0x13, 0x95, 0x48, 0xb6, 0x15, 0x35, 0x6e, 0xdd,
	0xb7, 0x6e, 0x05, 0xbf, 0x10, 0x3c, 0x89, 0x25, 0xe1, 0xb2, 0x39, 0x1a, 0xfa, 0xa3, 0xa6, 0x42,
	0xe2, 0x97, 0xe0, 0xdd, 0x1a, 0xef, 0xd3, 0x3c, 0x33, 0x2e, 0x80, 0x4d, 0x5d, 0x66, 0x78, 0x08,
	0xbd, 0xe6, 0xc8, 0x15, 0x6d, 0x67, 0xc9, 0x59, 0x63, 0xba, 0x97, 0x19, 0x0e, 0xe1, 0xfc, 0x80,
	0xab, 0x15, 0xb6, 0x34, 0xbb, 0xd7, 0x60, 0x2b, 0xa9, 0xc1, 0x05, 0x9c, 0x7e, 0x2b, 0x97, 0x84,
	0xc5, 0xb2, 0xe4, 0x64, 0x4d, 0x71, 0x08, 0xae, 0x7d, 0x59, 0xf8, 0x48, 0x6f, 0x48, 0xf7, 0x70,
	0x43, 0xa2, 0x3b, 0x4a, 0xf0, 0x1a, 0xdc, 0x7f, 0xfe, 0xa8, 0x35, 0x50, 0x06, 0x9b, 0x35, 0xa8,
	0x39, 0x53, 0x19, 0x4e, 0x57, 0x46, 0xac, 0x0a, 0x87, 0x73, 0x80, 0xbb, 0x19, 0xe1, 0xc7, 0x70,
	0x9e, 0x8c, 0xe3, 0xab, 0x34, 0x4e, 0xc6, 0xc9, 0x2c, 0x4e, 0x67, 0xd3, 0xab, 0xe9, 0xf5, 0x7c,
	0xda, 0xbd, 0x77, 0x08, 0x7c, 0x8e, 0x26, 0xe3, 0x64, 0xf2, 0xa5, 0x8b, 0x0e, 0x81, 0x38, 0x19,
	0x47, 0x0a, 0x70, 0x16, 0xbb, 0x3f, 0xe8, 0xed, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd3, 0xc2,
	0xf2, 0x91, 0x57, 0x03, 0x00, 0x00,
}
