// 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: prototype/client_profile_id.proto

package prototype

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

// Id of a client profile. See comment in client.proto for
// more details.
type ClientProfileId struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	// Required.
	Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
	// Required.
	ClientId *ClientId `protobuf:"bytes,2,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"`
}

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

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

func (*ClientProfileId) ProtoMessage() {}

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

func (x *ClientProfileId) GetId() string {
	if x != nil {
		return x.Id
	}
	return ""
}

func (x *ClientProfileId) GetClientId() *ClientId {
	if x != nil {
		return x.ClientId
	}
	return nil
}

var File_prototype_client_profile_id_proto protoreflect.FileDescriptor

var file_prototype_client_profile_id_proto_rawDesc = []byte{
	0x0a, 0x21, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x2f, 0x63, 0x6c, 0x69, 0x65,
	0x6e, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x2e, 0x70, 0x72,
	0x6f, 0x74, 0x6f, 0x12, 0x09, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x1a, 0x19,
	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
	0x5f, 0x69, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x53, 0x0a, 0x0f, 0x43, 0x6c, 0x69,
	0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02,
	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x09,
	0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
	0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x43, 0x6c, 0x69, 0x65,
	0x6e, 0x74, 0x49, 0x64, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x42, 0x35,
	0x5a, 0x33, 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, 0x70, 0x72, 0x6f, 0x74,
	0x6f, 0x74, 0x79, 0x70, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_prototype_client_profile_id_proto_rawDescOnce sync.Once
	file_prototype_client_profile_id_proto_rawDescData = file_prototype_client_profile_id_proto_rawDesc
)

func file_prototype_client_profile_id_proto_rawDescGZIP() []byte {
	file_prototype_client_profile_id_proto_rawDescOnce.Do(func() {
		file_prototype_client_profile_id_proto_rawDescData = protoimpl.X.CompressGZIP(file_prototype_client_profile_id_proto_rawDescData)
	})
	return file_prototype_client_profile_id_proto_rawDescData
}

var file_prototype_client_profile_id_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_prototype_client_profile_id_proto_goTypes = []interface{}{
	(*ClientProfileId)(nil), // 0: prototype.ClientProfileId
	(*ClientId)(nil),        // 1: prototype.ClientId
}
var file_prototype_client_profile_id_proto_depIdxs = []int32{
	1, // 0: prototype.ClientProfileId.client_id:type_name -> prototype.ClientId
	1, // [1:1] is the sub-list for method output_type
	1, // [1:1] is the sub-list for method input_type
	1, // [1:1] is the sub-list for extension type_name
	1, // [1:1] is the sub-list for extension extendee
	0, // [0:1] is the sub-list for field type_name
}

func init() { file_prototype_client_profile_id_proto_init() }
func file_prototype_client_profile_id_proto_init() {
	if File_prototype_client_profile_id_proto != nil {
		return
	}
	file_prototype_client_id_proto_init()
	if !protoimpl.UnsafeEnabled {
		file_prototype_client_profile_id_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ClientProfileId); 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_prototype_client_profile_id_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_prototype_client_profile_id_proto_goTypes,
		DependencyIndexes: file_prototype_client_profile_id_proto_depIdxs,
		MessageInfos:      file_prototype_client_profile_id_proto_msgTypes,
	}.Build()
	File_prototype_client_profile_id_proto = out.File
	file_prototype_client_profile_id_proto_rawDesc = nil
	file_prototype_client_profile_id_proto_goTypes = nil
	file_prototype_client_profile_id_proto_depIdxs = nil
}
