// Code generated by protoc-gen-go. DO NOT EDIT.
// source: client/request_id.proto

package client

import (
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

// Id of a client request. See comment in client/client.proto for
// more details.
type RequestId struct {
	// 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"`
	XXX_NoUnkeyedLiteral struct{}  `json:"-"`
	XXX_unrecognized     []byte    `json:"-"`
	XXX_sizecache        int32     `json:"-"`
}

func (m *RequestId) Reset()         { *m = RequestId{} }
func (m *RequestId) String() string { return proto.CompactTextString(m) }
func (*RequestId) ProtoMessage()    {}
func (*RequestId) Descriptor() ([]byte, []int) {
	return fileDescriptor_eb8829704834e2b3, []int{0}
}

func (m *RequestId) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_RequestId.Unmarshal(m, b)
}
func (m *RequestId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_RequestId.Marshal(b, m, deterministic)
}
func (m *RequestId) XXX_Merge(src proto.Message) {
	xxx_messageInfo_RequestId.Merge(m, src)
}
func (m *RequestId) XXX_Size() int {
	return xxx_messageInfo_RequestId.Size(m)
}
func (m *RequestId) XXX_DiscardUnknown() {
	xxx_messageInfo_RequestId.DiscardUnknown(m)
}

var xxx_messageInfo_RequestId proto.InternalMessageInfo

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

func (m *RequestId) GetClientId() *ClientId {
	if m != nil {
		return m.ClientId
	}
	return nil
}

func init() {
	proto.RegisterType((*RequestId)(nil), "client.RequestId")
}

func init() { proto.RegisterFile("client/request_id.proto", fileDescriptor_eb8829704834e2b3) }

var fileDescriptor_eb8829704834e2b3 = []byte{
	// 118 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4f, 0xce, 0xc9, 0x4c,
	0xcd, 0x2b, 0xd1, 0x2f, 0x4a, 0x2d, 0x2c, 0x4d, 0x2d, 0x2e, 0x89, 0xcf, 0x4c, 0xd1, 0x2b, 0x28,
	0xca, 0x2f, 0xc9, 0x17, 0x62, 0x83, 0x48, 0x48, 0x89, 0x41, 0x15, 0x40, 0x28, 0xb8, 0xbc, 0x92,
	0x17, 0x17, 0x67, 0x10, 0x44, 0x8f, 0x67, 0x8a, 0x10, 0x1f, 0x17, 0x53, 0x66, 0x8a, 0x04, 0xa3,
	0x02, 0xa3, 0x06, 0x67, 0x10, 0x53, 0x66, 0x8a, 0x90, 0x2e, 0x17, 0x27, 0x5c, 0xbd, 0x04, 0x93,
	0x02, 0xa3, 0x06, 0xb7, 0x91, 0x80, 0x1e, 0x44, 0x44, 0xcf, 0x19, 0x4c, 0x79, 0xa6, 0x04, 0x71,
	0x24, 0x43, 0x59, 0x49, 0x6c, 0x60, 0x23, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xdc, 0xcb,
	0x51, 0x7b, 0x8d, 0x00, 0x00, 0x00,
}
