// Copyright 2019 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: test_platform/skylab_local_state/common.proto

package skylab_local_state

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 skylab_local_state.
type Config struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	// Admin service host, e.g. foo.appspot.com.
	AdminService string `protobuf:"bytes,1,opt,name=admin_service,json=adminService,proto3" json:"admin_service,omitempty"`
	// Autotest directory on the drone, e.g. "/usr/local/autotest".
	AutotestDir string `protobuf:"bytes,2,opt,name=autotest_dir,json=autotestDir,proto3" json:"autotest_dir,omitempty"`
	// Inventory V2 service host, e.g. cros-lab-inventory.appspot.com.
	CrosInventoryService string `protobuf:"bytes,3,opt,name=cros_inventory_service,json=crosInventoryService,proto3" json:"cros_inventory_service,omitempty"`
	// Unified Fleet System service host, e.g. ufs.api.cr.dev.
	CrosUfsService string `protobuf:"bytes,4,opt,name=cros_ufs_service,json=crosUfsService,proto3" json:"cros_ufs_service,omitempty"`
}

func (x *Config) Reset() {
	*x = Config{}
	if protoimpl.UnsafeEnabled {
		mi := &file_test_platform_skylab_local_state_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_test_platform_skylab_local_state_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_test_platform_skylab_local_state_common_proto_rawDescGZIP(), []int{0}
}

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

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

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

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

var File_test_platform_skylab_local_state_common_proto protoreflect.FileDescriptor

var file_test_platform_skylab_local_state_common_proto_rawDesc = []byte{
	0x0a, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f,
	0x73, 0x6b, 0x79, 0x6c, 0x61, 0x62, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61,
	0x74, 0x65, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
	0x20, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x73,
	0x6b, 0x79, 0x6c, 0x61, 0x62, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x74,
	0x65, 0x22, 0xb0, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0d,
	0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20,
	0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
	0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x75, 0x74, 0x6f, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x64, 0x69,
	0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x75, 0x74, 0x6f, 0x74, 0x65, 0x73,
	0x74, 0x44, 0x69, 0x72, 0x12, 0x34, 0x0a, 0x16, 0x63, 0x72, 0x6f, 0x73, 0x5f, 0x69, 0x6e, 0x76,
	0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x03,
	0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x63, 0x72, 0x6f, 0x73, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74,
	0x6f, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x72,
	0x6f, 0x73, 0x5f, 0x75, 0x66, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x04,
	0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x72, 0x6f, 0x73, 0x55, 0x66, 0x73, 0x53, 0x65, 0x72,
	0x76, 0x69, 0x63, 0x65, 0x42, 0x4c, 0x5a, 0x4a, 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, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f,
	0x73, 0x6b, 0x79, 0x6c, 0x61, 0x62, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61,
	0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_test_platform_skylab_local_state_common_proto_rawDescOnce sync.Once
	file_test_platform_skylab_local_state_common_proto_rawDescData = file_test_platform_skylab_local_state_common_proto_rawDesc
)

func file_test_platform_skylab_local_state_common_proto_rawDescGZIP() []byte {
	file_test_platform_skylab_local_state_common_proto_rawDescOnce.Do(func() {
		file_test_platform_skylab_local_state_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_test_platform_skylab_local_state_common_proto_rawDescData)
	})
	return file_test_platform_skylab_local_state_common_proto_rawDescData
}

var file_test_platform_skylab_local_state_common_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_test_platform_skylab_local_state_common_proto_goTypes = []interface{}{
	(*Config)(nil), // 0: test_platform.skylab_local_state.Config
}
var file_test_platform_skylab_local_state_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_test_platform_skylab_local_state_common_proto_init() }
func file_test_platform_skylab_local_state_common_proto_init() {
	if File_test_platform_skylab_local_state_common_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_test_platform_skylab_local_state_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_test_platform_skylab_local_state_common_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_test_platform_skylab_local_state_common_proto_goTypes,
		DependencyIndexes: file_test_platform_skylab_local_state_common_proto_depIdxs,
		MessageInfos:      file_test_platform_skylab_local_state_common_proto_msgTypes,
	}.Build()
	File_test_platform_skylab_local_state_common_proto = out.File
	file_test_platform_skylab_local_state_common_proto_rawDesc = nil
	file_test_platform_skylab_local_state_common_proto_goTypes = nil
	file_test_platform_skylab_local_state_common_proto_depIdxs = nil
}
