// Copyright 2024 Google LLC
//
// Licensed 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.34.1
// 	protoc        v4.25.3
// source: google/chat/v1/slash_command.proto

package chatpb

import (
	reflect "reflect"
	sync "sync"

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

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)
)

// A [slash
// command](https://developers.google.com/workspace/chat/slash-commands) in
// Google Chat.
type SlashCommand struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	// The ID of the slash command invoked.
	CommandId int64 `protobuf:"varint,1,opt,name=command_id,json=commandId,proto3" json:"command_id,omitempty"`
}

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

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

func (*SlashCommand) ProtoMessage() {}

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

func (x *SlashCommand) GetCommandId() int64 {
	if x != nil {
		return x.CommandId
	}
	return 0
}

var File_google_chat_v1_slash_command_proto protoreflect.FileDescriptor

var file_google_chat_v1_slash_command_proto_rawDesc = []byte{
	0x0a, 0x22, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x68, 0x61, 0x74, 0x2f, 0x76, 0x31,
	0x2f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x70,
	0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x68, 0x61,
	0x74, 0x2e, 0x76, 0x31, 0x22, 0x2d, 0x0a, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x43, 0x6f, 0x6d,
	0x6d, 0x61, 0x6e, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f,
	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
	0x64, 0x49, 0x64, 0x42, 0xaa, 0x01, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
	0x6c, 0x65, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x76, 0x31, 0x42, 0x11, 0x53, 0x6c, 0x61, 0x73,
	0x68, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
	0x2c, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
	0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x63, 0x68, 0x61, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x31, 0x2f,
	0x63, 0x68, 0x61, 0x74, 0x70, 0x62, 0x3b, 0x63, 0x68, 0x61, 0x74, 0x70, 0x62, 0xa2, 0x02, 0x0b,
	0x44, 0x59, 0x4e, 0x41, 0x50, 0x49, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0xaa, 0x02, 0x13, 0x47, 0x6f,
	0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x74, 0x2e, 0x56,
	0x31, 0xca, 0x02, 0x13, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x41, 0x70, 0x70, 0x73, 0x5c,
	0x43, 0x68, 0x61, 0x74, 0x5c, 0x56, 0x31, 0xea, 0x02, 0x16, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
	0x3a, 0x3a, 0x41, 0x70, 0x70, 0x73, 0x3a, 0x3a, 0x43, 0x68, 0x61, 0x74, 0x3a, 0x3a, 0x56, 0x31,
	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_google_chat_v1_slash_command_proto_rawDescOnce sync.Once
	file_google_chat_v1_slash_command_proto_rawDescData = file_google_chat_v1_slash_command_proto_rawDesc
)

func file_google_chat_v1_slash_command_proto_rawDescGZIP() []byte {
	file_google_chat_v1_slash_command_proto_rawDescOnce.Do(func() {
		file_google_chat_v1_slash_command_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_chat_v1_slash_command_proto_rawDescData)
	})
	return file_google_chat_v1_slash_command_proto_rawDescData
}

var file_google_chat_v1_slash_command_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_google_chat_v1_slash_command_proto_goTypes = []interface{}{
	(*SlashCommand)(nil), // 0: google.chat.v1.SlashCommand
}
var file_google_chat_v1_slash_command_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_google_chat_v1_slash_command_proto_init() }
func file_google_chat_v1_slash_command_proto_init() {
	if File_google_chat_v1_slash_command_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_google_chat_v1_slash_command_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*SlashCommand); 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_google_chat_v1_slash_command_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_google_chat_v1_slash_command_proto_goTypes,
		DependencyIndexes: file_google_chat_v1_slash_command_proto_depIdxs,
		MessageInfos:      file_google_chat_v1_slash_command_proto_msgTypes,
	}.Build()
	File_google_chat_v1_slash_command_proto = out.File
	file_google_chat_v1_slash_command_proto_rawDesc = nil
	file_google_chat_v1_slash_command_proto_goTypes = nil
	file_google_chat_v1_slash_command_proto_depIdxs = nil
}
