// Code generated by protoc-gen-go. DO NOT EDIT.
// source: uprev/build_parallels_image/common.proto

package build_parallels_image

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

// Config defines configuration parameters of `phosphorus build-parallels-image-*` commands.
type Config struct {
	// Unified Fleet System service host, e.g. ufs.api.cr.dev.
	CrosUfsService       string   `protobuf:"bytes,1,opt,name=cros_ufs_service,json=crosUfsService,proto3" json:"cros_ufs_service,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_Config proto.InternalMessageInfo

func (m *Config) GetCrosUfsService() string {
	if m != nil {
		return m.CrosUfsService
	}
	return ""
}

func init() {
	proto.RegisterType((*Config)(nil), "uprev.build_parallels_image.Config")
}

func init() {
	proto.RegisterFile("uprev/build_parallels_image/common.proto", fileDescriptor_0fbba075d2a19ce4)
}

var fileDescriptor_0fbba075d2a19ce4 = []byte{
	// 162 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0xce, 0xb1, 0x0a, 0xc2, 0x30,
	0x10, 0xc6, 0x71, 0xba, 0x14, 0xec, 0x20, 0xd2, 0x49, 0x70, 0x11, 0xa7, 0x4e, 0x39, 0xd0, 0x37,
	0x50, 0xc4, 0x5d, 0x71, 0x71, 0x09, 0x69, 0x4c, 0xe2, 0x41, 0xd2, 0x2b, 0x77, 0xa6, 0xcf, 0x2f,
	0x46, 0xdc, 0xc4, 0xf1, 0xfe, 0xfc, 0xe0, 0xbe, 0xa6, 0xcb, 0x23, 0xbb, 0x09, 0xfa, 0x8c, 0xf1,
	0xae, 0x47, 0xc3, 0x26, 0x46, 0x17, 0x45, 0x63, 0x32, 0xc1, 0x81, 0xa5, 0x94, 0x68, 0x50, 0x23,
	0xd3, 0x93, 0xda, 0x55, 0x91, 0xea, 0xa7, 0xdc, 0x6c, 0x9b, 0xfa, 0x40, 0x83, 0xc7, 0xd0, 0x76,
	0xcd, 0xc2, 0x32, 0x89, 0xce, 0x5e, 0xb4, 0x38, 0x9e, 0xd0, 0xba, 0x65, 0xb5, 0xae, 0xba, 0xd9,
	0x79, 0xfe, 0xee, 0x57, 0x2f, 0x97, 0x4f, 0xdd, 0x9f, 0x6e, 0xc7, 0x40, 0xca, 0x3e, 0x98, 0x12,
	0xe6, 0xa4, 0x88, 0x03, 0x7c, 0x0f, 0x12, 0xc0, 0xc1, 0xb3, 0x81, 0xf2, 0x1a, 0x02, 0xc1, 0x9f,
	0x99, 0x7d, 0x5d, 0xd4, 0xee, 0x15, 0x00, 0x00, 0xff, 0xff, 0x73, 0x69, 0x2c, 0xe7, 0xcc, 0x00,
	0x00, 0x00,
}
