// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.25.0-devel
// 	protoc        v3.6.1
// source: uprev/build_parallels_image/common.proto

package build_parallels_image

import (
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

// Config defines configuration parameters of `phosphorus build-parallels-image-*` commands.
type Config struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	// 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"`
}

func (x *Config) Reset() {
	*x = Config{}
	if protoimpl.UnsafeEnabled {
		mi := &file_uprev_build_parallels_image_common_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *Config) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Config) ProtoMessage() {}

func (x *Config) ProtoReflect() protoreflect.Message {
	mi := &file_uprev_build_parallels_image_common_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Config.ProtoReflect.Descriptor instead.
func (*Config) Descriptor() ([]byte, []int) {
	return file_uprev_build_parallels_image_common_proto_rawDescGZIP(), []int{0}
}

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

var File_uprev_build_parallels_image_common_proto protoreflect.FileDescriptor

var file_uprev_build_parallels_image_common_proto_rawDesc = []byte{
	0x0a, 0x28, 0x75, 0x70, 0x72, 0x65, 0x76, 0x2f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x70, 0x61,
	0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x73, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x63, 0x6f,
	0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x75, 0x70, 0x72, 0x65,
	0x76, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c,
	0x73, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x22, 0x32, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69,
	0x67, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x72, 0x6f, 0x73, 0x5f, 0x75, 0x66, 0x73, 0x5f, 0x73, 0x65,
	0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x72, 0x6f,
	0x73, 0x55, 0x66, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x47, 0x5a, 0x45, 0x67,
	0x6f, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x63,
	0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x6f, 0x73, 0x2f, 0x69, 0x6e, 0x66, 0x72, 0x61, 0x2f,
	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x75, 0x70, 0x72, 0x65, 0x76, 0x2f, 0x62,
	0x75, 0x69, 0x6c, 0x64, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x73, 0x5f, 0x69,
	0x6d, 0x61, 0x67, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_uprev_build_parallels_image_common_proto_rawDescOnce sync.Once
	file_uprev_build_parallels_image_common_proto_rawDescData = file_uprev_build_parallels_image_common_proto_rawDesc
)

func file_uprev_build_parallels_image_common_proto_rawDescGZIP() []byte {
	file_uprev_build_parallels_image_common_proto_rawDescOnce.Do(func() {
		file_uprev_build_parallels_image_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_uprev_build_parallels_image_common_proto_rawDescData)
	})
	return file_uprev_build_parallels_image_common_proto_rawDescData
}

var file_uprev_build_parallels_image_common_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_uprev_build_parallels_image_common_proto_goTypes = []interface{}{
	(*Config)(nil), // 0: uprev.build_parallels_image.Config
}
var file_uprev_build_parallels_image_common_proto_depIdxs = []int32{
	0, // [0:0] is the sub-list for method output_type
	0, // [0:0] is the sub-list for method input_type
	0, // [0:0] is the sub-list for extension type_name
	0, // [0:0] is the sub-list for extension extendee
	0, // [0:0] is the sub-list for field type_name
}

func init() { file_uprev_build_parallels_image_common_proto_init() }
func file_uprev_build_parallels_image_common_proto_init() {
	if File_uprev_build_parallels_image_common_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_uprev_build_parallels_image_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Config); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_uprev_build_parallels_image_common_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_uprev_build_parallels_image_common_proto_goTypes,
		DependencyIndexes: file_uprev_build_parallels_image_common_proto_depIdxs,
		MessageInfos:      file_uprev_build_parallels_image_common_proto_msgTypes,
	}.Build()
	File_uprev_build_parallels_image_common_proto = out.File
	file_uprev_build_parallels_image_common_proto_rawDesc = nil
	file_uprev_build_parallels_image_common_proto_goTypes = nil
	file_uprev_build_parallels_image_common_proto_depIdxs = nil
}
