//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.26.0
// 	protoc        v3.14.0
// source: language-agent/ConfigurationDiscoveryService.proto

package v3

import (
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	v3 "skywalking.apache.org/repo/goapi/collect/common/v3"
	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)
)

type ConfigurationSyncRequest struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	// Current agent service name.
	Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
	// [Optional]
	// UUID is the unique id to represent the signature of the latest configuration.
	// The agent usually uses its bootstrap configuration running in default, and this id could be empty when doing the 1st round sync.
	// The agent could/is recommended to cache the UUID from the last command, and put it as the next round UUID parameter,
	// then the OAP only returns the empty Commands if no configuration change happenned.
	Uuid string `protobuf:"bytes,2,opt,name=uuid,proto3" json:"uuid,omitempty"`
}

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

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

func (*ConfigurationSyncRequest) ProtoMessage() {}

func (x *ConfigurationSyncRequest) ProtoReflect() protoreflect.Message {
	mi := &file_language_agent_ConfigurationDiscoveryService_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 ConfigurationSyncRequest.ProtoReflect.Descriptor instead.
func (*ConfigurationSyncRequest) Descriptor() ([]byte, []int) {
	return file_language_agent_ConfigurationDiscoveryService_proto_rawDescGZIP(), []int{0}
}

func (x *ConfigurationSyncRequest) GetService() string {
	if x != nil {
		return x.Service
	}
	return ""
}

func (x *ConfigurationSyncRequest) GetUuid() string {
	if x != nil {
		return x.Uuid
	}
	return ""
}

var File_language_agent_ConfigurationDiscoveryService_proto protoreflect.FileDescriptor

var file_language_agent_ConfigurationDiscoveryService_proto_rawDesc = []byte{
	0x0a, 0x32, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74,
	0x2f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x69,
	0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70,
	0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67,
	0x2e, 0x76, 0x33, 0x1a, 0x13, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x43, 0x6f, 0x6d, 0x6d,
	0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x48, 0x0a, 0x18, 0x43, 0x6f, 0x6e, 0x66,
	0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71,
	0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18,
	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x12,
	0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75,
	0x69, 0x64, 0x32, 0x7a, 0x0a, 0x1d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74,
	0x69, 0x6f, 0x6e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76,
	0x69, 0x63, 0x65, 0x12, 0x59, 0x0a, 0x13, 0x66, 0x65, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66,
	0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x27, 0x2e, 0x73, 0x6b, 0x79,
	0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69,
	0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75,
	0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67,
	0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x00, 0x42, 0x98,
	0x01, 0x0a, 0x33, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x73, 0x6b,
	0x79, 0x77, 0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x61, 0x70, 0x6d, 0x2e, 0x6e, 0x65, 0x74,
	0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x61, 0x67,
	0x65, 0x6e, 0x74, 0x2e, 0x76, 0x33, 0x50, 0x01, 0x5a, 0x3f, 0x73, 0x6b, 0x79, 0x77, 0x61, 0x6c,
	0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x2f,
	0x72, 0x65, 0x70, 0x6f, 0x2f, 0x67, 0x6f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6c, 0x6c, 0x65,
	0x63, 0x74, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75,
	0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x33, 0xaa, 0x02, 0x1d, 0x53, 0x6b, 0x79, 0x57,
	0x61, 0x6c, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x50, 0x72,
	0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x56, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
	0x33,
}

var (
	file_language_agent_ConfigurationDiscoveryService_proto_rawDescOnce sync.Once
	file_language_agent_ConfigurationDiscoveryService_proto_rawDescData = file_language_agent_ConfigurationDiscoveryService_proto_rawDesc
)

func file_language_agent_ConfigurationDiscoveryService_proto_rawDescGZIP() []byte {
	file_language_agent_ConfigurationDiscoveryService_proto_rawDescOnce.Do(func() {
		file_language_agent_ConfigurationDiscoveryService_proto_rawDescData = protoimpl.X.CompressGZIP(file_language_agent_ConfigurationDiscoveryService_proto_rawDescData)
	})
	return file_language_agent_ConfigurationDiscoveryService_proto_rawDescData
}

var file_language_agent_ConfigurationDiscoveryService_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_language_agent_ConfigurationDiscoveryService_proto_goTypes = []interface{}{
	(*ConfigurationSyncRequest)(nil), // 0: skywalking.v3.ConfigurationSyncRequest
	(*v3.Commands)(nil),              // 1: skywalking.v3.Commands
}
var file_language_agent_ConfigurationDiscoveryService_proto_depIdxs = []int32{
	0, // 0: skywalking.v3.ConfigurationDiscoveryService.fetchConfigurations:input_type -> skywalking.v3.ConfigurationSyncRequest
	1, // 1: skywalking.v3.ConfigurationDiscoveryService.fetchConfigurations:output_type -> skywalking.v3.Commands
	1, // [1:2] is the sub-list for method output_type
	0, // [0:1] 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_language_agent_ConfigurationDiscoveryService_proto_init() }
func file_language_agent_ConfigurationDiscoveryService_proto_init() {
	if File_language_agent_ConfigurationDiscoveryService_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_language_agent_ConfigurationDiscoveryService_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ConfigurationSyncRequest); 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_language_agent_ConfigurationDiscoveryService_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   1,
		},
		GoTypes:           file_language_agent_ConfigurationDiscoveryService_proto_goTypes,
		DependencyIndexes: file_language_agent_ConfigurationDiscoveryService_proto_depIdxs,
		MessageInfos:      file_language_agent_ConfigurationDiscoveryService_proto_msgTypes,
	}.Build()
	File_language_agent_ConfigurationDiscoveryService_proto = out.File
	file_language_agent_ConfigurationDiscoveryService_proto_rawDesc = nil
	file_language_agent_ConfigurationDiscoveryService_proto_goTypes = nil
	file_language_agent_ConfigurationDiscoveryService_proto_depIdxs = nil
}
