text:
#ifndef DG_LLVM_CALLGRAPH_H_
#define DG_LLVM_CALLGRAPH_H_

#include <memory>
#include <vector>

#include <llvm/IR/Function.h>
#include <llvm/IR/InstIterator.h>
#include <llvm/IR/Module.h>

#include "dg/ADT/HashMap.h"
#include "dg/ADT/Queue.h"
#include "dg/ADT/SetQueue.h"
#include "dg/CallGraph/CallGraph.h"
#include "dg/PointerAnalysis/PSNode.h"
#include "dg/llvm/PointerAnalysis/PointerAnalysis.h"

namespace dg {
namespace pta {
class PSNode;
}

namespace llvmdg {

class CallGraphImpl {
  public:
    using FuncVec = std::vector<const llvm::Function *>;

    virtual ~CallGraphImpl() = default;

    // XXX: return iterators...

    ///
    /// \brief functions
    /// \return Functions that are in the callgraph. Note that there may be
    /// functions missing if the callgraph is being build lazily
    /// (you may force building CG by build() method).
    ///
    virtual FuncVec functions() const = 0;
    virtual FuncVec callers(const llvm::Function *) = 0;
    virtual FuncVec callees(const llvm::Function *) = 0;
    virtual bool calls(const llvm::Function *, const llvm::Function *) = 0;

    // trigger building the CG (can be used to force building when CG is
    // constructed on demand)
    virtual void build() {}
};

///
/// Callgraph that re-uses the Call graph built during pointer analysis from DG
///
class DGCallGraphImpl : public CallGraphImpl {
    const GenericCallGraph<PSNode *> &_cg;
    std::map<const llvm::Function *, PSNode *> _mapping;

    static const llvm::Function *getFunFromNode(PSNode *n) {
        auto *f = n->getUserData<llvm::Function>();
        assert(f && "Invalid data in a node");
        return f;
    }

  public:
    DGCallGraphImpl(const dg::GenericCallGraph<PSNode *> &cg) : _cg(cg) {
        for (const auto &it : _cg) {
            _mapping[getFunFromNode(it.first)] = it.first;
        }
    }

    FuncVec functions() const override {
        FuncVec ret;
        for (const auto &it : _mapping) {
            ret.push_back(it.first);
        }
        return ret;
    }

    FuncVec callers(const llvm::Function *F) override {
        FuncVec ret;
        auto it = _mapping.find(F);
        if (it == _mapping.end())
            return ret;
        const auto *fnd = _cg.get(it->second);
        for (auto *nd : fnd->getCallers()) {
            ret.push_back(getFunFromNode(nd->getValue()));
        }
        return ret;
    }

    FuncVec callees(const llvm::Function *F) override {
        FuncVec ret;
        auto it = _mapping.find(F);
        if (it == _mapping.end())
            return ret;
        const auto *fnd = _cg.get(it->second);
        for (auto *nd : fnd->getCalls()) {
            ret.push_back(getFunFromNode(nd->getValue()));
        }
        return ret;
    }

    bool calls(const llvm::Function *F, const llvm::Function *what) override {
        auto it = _mapping.find(F);
        if (it == _mapping.end())
            return false;
        auto it2 = _mapping.find(what);
        if (it2 == _mapping.end())
            return false;
        const auto *fn1 = _cg.get(it->second);
        const auto *fn2 = _cg.get(it2->second);
        if (fn1 && fn2) {
            return fn1->calls(fn2);
        }
        return false;
    };
};

// FIXME: copied from llvm-utils.h
namespace {
inline bool isPointerOrIntegerTy(const llvm::Type *Ty) {
    return Ty->isPointerTy() || Ty->isIntegerTy();
}

// can the given function be called by the given call inst?
enum class CallCompatibility {
    STRICT,       // require full compatibility
    LOOSE,        // ignore some incompatible patterns that usually work
                  // in practice, e.g., calling a function of 2 arguments
                  // with 3 arguments.
    MATCHING_ARGS // check only that matching arguments are compatible,
                  // ignore the number of arguments, etc.
};

inline bool
callIsCompatible(const llvm::Function *F, const llvm::CallInst *CI,
                 CallCompatibility policy = CallCompatibility::LOOSE) {
    using namespace llvm;

#if LLVM_VERSION_MAJOR >= 8
    auto max_idx = CI->arg_size();
#else
    auto max_idx = CI->getNumArgOperands();
#endif

    if (policy != CallCompatibility::MATCHING_ARGS) {
        if (F->isVarArg()) {
            if (F->arg_size() > max_idx) {
                return false;
            }
        } else if (F->arg_size() != max_idx) {
            if (policy == CallCompatibility::STRICT ||
                F->arg_size() > max_idx) {
                // too few arguments
                return false;
            }
        }

        if (!F->getReturnType()->canLosslesslyBitCastTo(CI->getType())) {
            // it showed up that the loosless bitcast is too strict
            // alternative since we can use the constexpr castings
            if (!(isPointerOrIntegerTy(F->getReturnType()) &&
                  isPointerOrIntegerTy(CI->getType()))) {
                return false;
            }
        }
    }

    size_t idx = 0;
    for (auto A = F->arg_begin(), E = F->arg_end(); idx < max_idx && A != E;
         ++A, ++idx) {
        Type *CTy = CI->getArgOperand(idx)->getType();
        Type *ATy = A->getType();

        if (!(isPointerOrIntegerTy(CTy) && isPointerOrIntegerTy(ATy)))
            if (!CTy->canLosslesslyBitCastTo(ATy)) {
                return false;
            }
    }

    return true;
}
} // anonymous namespace

///
/// Callgraph that is built based on the results of pointer analysis.
/// This class has been superseeded by LazyLLVMCallGraph.
///
class LLVMPTACallGraphImpl : public CallGraphImpl {
    GenericCallGraph<const llvm::Function *> _cg{};
    const llvm::Module *_module;
    LLVMPointerAnalysis *_pta;

    void
    processBBlock(const llvm::Function *parent, const llvm::BasicBlock &B,
                  ADT::SetQueue<QueueFIFO<const llvm::Function *>> &queue) {
        for (const auto &I : B) {
            if (const auto *C = llvm::dyn_cast<llvm::CallInst>(&I)) {
#if LLVM_VERSION_MAJOR >= 8
                auto pts = _pta->getLLVMPointsTo(C->getCalledOperand());
#else
                auto pts = _pta->getLLVMPointsTo(C->getCalledValue());
#endif
                for (const auto &ptr : pts) {
                    auto *F = llvm::dyn_cast<llvm::Function>(ptr.value);
                    if (!F || !callIsCompatible(F, C))
                        continue;

                    _cg.addCall(parent, F);
                    queue.push(F);
                }
            }
        }
    }

    void _build() {
        auto *entry = _module->getFunction(_pta->getOptions().entryFunction);
        assert(entry && "Entry function not found");
        _cg.createNode(entry);

        ADT::SetQueue<QueueFIFO<const llvm::Function *>> queue;
        queue.push(entry);

        while (!queue.empty()) {
            const auto *cur = queue.pop();
            for (const auto &B : *cur) {
                processBBlock(cur, B, queue);
            }
        }
    }

  public:
    LLVMPTACallGraphImpl(const llvm::Module *m, LLVMPointerAnalysis *pta)
            : _module(m), _pta(pta) {
        _build();
    }

    FuncVec functions() const override {
        FuncVec ret;
        for (const auto &it : _cg) {
            ret.push_back(it.first);
        }
        return ret;
    }

    FuncVec callers(const llvm::Function *F) override {
        FuncVec ret;
        const auto *fnd = _cg.get(F);
        for (auto *nd : fnd->getCallers()) {
            ret.push_back(nd->getValue());
        }
        return ret;
    }

    FuncVec callees(const llvm::Function *F) override {
        FuncVec ret;
        const auto *fnd = _cg.get(F);
        for (auto *nd : fnd->getCalls()) {
            ret.push_back(nd->getValue());
        }
        return ret;
    }

    bool calls(const llvm::Function *F, const llvm::Function *what) override {
        const auto *fn1 = _cg.get(F);
        const auto *fn2 = _cg.get(what);
        if (fn1 && fn2) {
            return fn1->calls(fn2);
        }
        return false;
    };
};

inline bool funHasAddressTaken(const llvm::Function *fun) {
    using namespace llvm;
    for (auto &use : fun->uses()) {
#if ((LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR < 5))
        Value *user = *use;
#else
        Value *user = use.getUser();
#endif
        // FIXME: we can detect more cases as false
        if (auto *C = dyn_cast<CallInst>(user)) {
            if (fun == C->getCalledFunction()) {
                continue;
            }
        }
        return true;
    }
    return false;
}

///
/// \brief The LazyLLVMCallGraph class
///
/// A callgraph that is being build lazily based on user queries.
/// It can use pointer analysis, but it is sound even without it
/// (by overapproximating).
class LazyLLVMCallGraph : public CallGraphImpl {
    GenericCallGraph<const llvm::Function *> _cg{};
    const llvm::Module *_module;
    LLVMPointerAnalysis *_pta;

    using FuncVec = CallGraphImpl::FuncVec;
    // resolved function pointers
    dg::HashMap<const llvm::CallInst *, FuncVec> _funptrs;
    std::vector<const llvm::Function *> _address_taken;
    bool _address_taken_initialized{false};
    // resolved callers of address-taken functions
    dg::HashMap<const llvm::Function *, std::vector<const llvm::CallInst *>>
            _callsOf;

    inline const llvm::Value *_getCalledValue(const llvm::CallInst *C) const {
#if LLVM_VERSION_MAJOR >= 8
        return C->getCalledOperand()->stripPointerCasts();
#else
        return C->getCalledValue()->stripPointerCasts();
#endif
    }

    void _initializeAddressTaken() {
        assert(!_address_taken_initialized);
        _address_taken_initialized = true;

        for (auto &F : *_module) {
            if (F.isDeclaration())
                continue;
            if (funHasAddressTaken(&F)) {
                _address_taken.push_back(&F);
            }
        }
    }

    FuncVec _getAddressTakenFuns(const llvm::CallInst *C) {
        // FIXME: check that C calls initialized values
        // (in many non-executable pieces of code, the call may call
        // an uninitialized function pointer. Return no function
        // in such cases instead of all address taken functions.
        if (!_address_taken_initialized)
            _initializeAddressTaken();
        assert(_address_taken_initialized);

        FuncVec ret;
        // filter out compatible functions
        for (auto *fun : _address_taken) {
            if (callIsCompatible(fun, C)) {
                ret.push_back(fun);
            }
        }
        return ret;
    }

    // we pass also the call inst to be able to filter out incompatible
    // functions
    FuncVec _getCalledFunctions(const llvm::CallInst *C,
                                const llvm::Value *val) {
        if (_pta) {
            FuncVec ret;
            auto pts = _pta->getLLVMPointsTo(val);
            for (const auto &ptr : pts) {
                if (auto *fun = llvm::dyn_cast<llvm::Function>(ptr.value)) {
                    if (callIsCompatible(fun, C)) {
                        ret.push_back(fun);
                    }
                }
            }
            return ret;
        } else {
            return _getAddressTakenFuns(C);
        }
    }

    FuncVec _getCalledFunctions(const llvm::CallInst *C) {
        auto *callval = _getCalledValue(C);
        assert(!llvm::isa<llvm::Function>(callval) &&
               "This method should be called on funptr");
        auto *thisf = C->getParent()->getParent();
        auto ret = _getCalledFunctions(C, callval);
        for (auto *f : ret)
            _cg.addCall(thisf, f);
        return ret;
    }

    bool hasFn(const llvm::Function *fun) const {
        return _cg.get(fun) != nullptr;
    }

    void _populateCalledFunctions(const llvm::Function *fun) {
        for (auto &B : *fun) {
            for (auto &I : B) {
                if (auto *C = llvm::dyn_cast<llvm::CallInst>(&I)) {
                    getCalledFunctions(C);
                }
            }
        }
    }

    void
    processBBlock(const llvm::Function *parent, const llvm::BasicBlock &B,
                  ADT::SetQueue<QueueFIFO<const llvm::Function *>> &queue) {
        assert(_pta && "This method can be used only with PTA");
        for (auto &I : B) {
            if (auto *C = llvm::dyn_cast<llvm::CallInst>(&I)) {
                auto pts = _pta->getLLVMPointsTo(_getCalledValue(C));
                for (const auto &ptr : pts) {
                    if (auto *F = llvm::dyn_cast<llvm::Function>(ptr.value)) {
                        if (callIsCompatible(F, C)) {
                            _cg.addCall(parent, F);
                            queue.push(F);
                        }
                    }
                }
            }
        }
    }

    // FIXME: if we have _pta, use the callgraph from _pta if available
    const std::vector<const llvm::CallInst *> &
    getCallsOfAddressTaken(const llvm::Function *F) {
        assert(funHasAddressTaken(F));

        // if we already computed this, return the cached result
        auto it = _callsOf.find(F);
        if (it != _callsOf.end())
            return it->second;

        // FIXME: could we do this more efficient?
        // We could gather funptr calls and iterate only over those
        // + get regular calls from the uses of F...
        std::vector<const llvm::CallInst *> ret;
        for (auto &mfun : *_module) {
            for (auto &B : mfun) {
                for (auto &I : B) {
                    auto *C = llvm::dyn_cast<llvm::CallInst>(&I);
                    if (!C)
                        continue;

                    for (auto *calledf : getCalledFunctions(C)) {
                        if (calledf == F) {
                            _cg.addCall(&mfun, F);
                            ret.push_back(C);
                        }
                    }
                }
            }
        }

        // FIXME: double access...
        _callsOf[F] = ret;
        return _callsOf[F];
    }

  public:
    LazyLLVMCallGraph(const llvm::Module *m, LLVMPointerAnalysis *pta = nullptr)
            : _module(m), _pta(pta) {}

    // TODO: add this method to general interface?
    const FuncVec &getCalledFunctions(const llvm::CallInst *C) {
        auto *val = _getCalledValue(C);
        if (auto *fun = llvm::dyn_cast<llvm::Function>(val)) {
            static FuncVec retval;
            retval.clear();
            retval.push_back(fun);
            _cg.addCall(C->getParent()->getParent(), fun);
            return retval;
        }

        auto it = _funptrs.find(C);
        if (it != _funptrs.end()) {
            return it->second;
        }

        // FIXME: do not do multiple lookups
        _funptrs[C] = _getCalledFunctions(C);
        return _funptrs[C];
    }

    std::vector<const llvm::CallInst *> getCallsOf(const llvm::Function *F) {
        if (funHasAddressTaken(F)) {
            return getCallsOfAddressTaken(F);
        }

        // has not address taken, so all users are calls
        std::vector<const llvm::CallInst *> ret;
        for (auto &use : F->uses()) {
#if ((LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR < 5))
            auto *user = *use;
#else
            auto *user = use.getUser();
#endif
            auto *C = llvm::cast<llvm::CallInst>(user);
            _cg.addCall(C->getParent()->getParent(), F);
            ret.push_back(C);
        }
        return ret;
    }

    FuncVec functions() const override {
        FuncVec ret;
        for (auto &it : _cg) {
            ret.push_back(it.first);
        }
        return ret;
    }

    FuncVec callers(const llvm::Function *F) override {
        FuncVec ret;
        // make sure we have the callers
        // (this will find also caller functions)
        getCallsOf(F);

        auto fnd = _cg.get(F);
        assert(fnd);
        for (auto *nd : fnd->getCallers()) {
            ret.push_back(nd->getValue());
        }
        return ret;
    }

    FuncVec callees(const llvm::Function *F) override {
        FuncVec ret;
        if (!hasFn(F)) {
            _populateCalledFunctions(F);
        }
        auto fnd = _cg.get(F);
        for (auto *nd : fnd->getCalls()) {
            ret.push_back(nd->getValue());
        }
        return ret;
    }

    bool calls(const llvm::Function *F, const llvm::Function *what) override {
        if (!hasFn(F)) {
            _populateCalledFunctions(F);
        }
        auto fn1 = _cg.get(F);
        auto fn2 = _cg.get(what);
        if (fn1 && fn2) {
            return fn1->calls(fn2);
        }
        return false;
    };

    // trigger build
    void build() override {
        if (_pta) { // build only reachable functions
            auto *entry =
                    _module->getFunction(_pta->getOptions().entryFunction);
            assert(entry && "Entry function not found");
            _cg.createNode(entry);

            ADT::SetQueue<QueueFIFO<const llvm::Function *>> queue;
            queue.push(entry);

            while (!queue.empty()) {
                auto *cur = queue.pop();
                for (auto &B : *cur) {
                    processBBlock(cur, B, queue);
                }
            }
        } else {
            for (auto &F : *_module) {
                if (F.isDeclaration())
                    continue;
                _populateCalledFunctions(&F);
            }
        }
    }
};

class CallGraph {
    std::unique_ptr<CallGraphImpl> _impl;

  public:
    using FuncVec = CallGraphImpl::FuncVec;

    CallGraph(GenericCallGraph<PSNode *> &cg)
            : _impl(new DGCallGraphImpl(cg)) {}
    CallGraph(const llvm::Module *m, LLVMPointerAnalysis *pta, bool lazy = true)
            : _impl(lazy ? static_cast<CallGraphImpl *>(
                                   new LazyLLVMCallGraph(m, pta))
                         : static_cast<CallGraphImpl *>(
                                   new LLVMPTACallGraphImpl(m, pta))) {}
    CallGraph(const llvm::Module *m) : _impl(new LazyLLVMCallGraph(m)) {}

    ///
    /// Get all functions in this call graph
    ///
    FuncVec functions() const { return _impl->functions(); }
    ///
    /// Get callers of a function
    ///
    FuncVec callers(const llvm::Function *F) { return _impl->callers(F); };
    ///
    /// Get functions called from the given function
    ///
    FuncVec callees(const llvm::Function *F) { return _impl->callees(F); };
    ///
    /// Return true if function 'F' calls 'what'
    ///
    bool calls(const llvm::Function *F, const llvm::Function *what) {
        return _impl->calls(F, what);
    };

    void build() { _impl->build(); }
};

} // namespace llvmdg
} // namespace dg

#endif

repository: mchalupa/dg

repo_name: mchalupa/dg

gha_license_id: MIT

extension: h


text:
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.26.0
// 	protoc        v3.7.0
// source: pkg/lmproxyproto/cmd.proto

package lmproxyproto

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

type Status int32

const (
	Status_Error   Status = 0
	Status_Success Status = 1
)

// Enum value maps for Status.
var (
	Status_name = map[int32]string{
		0: "Error",
		1: "Success",
	}
	Status_value = map[string]int32{
		"Error":   0,
		"Success": 1,
	}
)

func (x Status) Enum() *Status {
	p := new(Status)
	*p = x
	return p
}

func (x Status) String() string {
	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}

func (Status) Descriptor() protoreflect.EnumDescriptor {
	return file_pkg_lmproxyproto_cmd_proto_enumTypes[0].Descriptor()
}

func (Status) Type() protoreflect.EnumType {
	return &file_pkg_lmproxyproto_cmd_proto_enumTypes[0]
}

func (x Status) Number() protoreflect.EnumNumber {
	return protoreflect.EnumNumber(x)
}

// Deprecated: Use Status.Descriptor instead.
func (Status) EnumDescriptor() ([]byte, []int) {
	return file_pkg_lmproxyproto_cmd_proto_rawDescGZIP(), []int{0}
}

type Role int32

const (
	Role_Unknown Role = 0
	Role_Master  Role = 1
	Role_Slave   Role = 2
)

// Enum value maps for Role.
var (
	Role_name = map[int32]string{
		0: "Unknown",
		1: "Master",
		2: "Slave",
	}
	Role_value = map[string]int32{
		"Unknown": 0,
		"Master":  1,
		"Slave":   2,
	}
)

func (x Role) Enum() *Role {
	p := new(Role)
	*p = x
	return p
}

func (x Role) String() string {
	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}

func (Role) Descriptor() protoreflect.EnumDescriptor {
	return file_pkg_lmproxyproto_cmd_proto_enumTypes[1].Descriptor()
}

func (Role) Type() protoreflect.EnumType {
	return &file_pkg_lmproxyproto_cmd_proto_enumTypes[1]
}

func (x Role) Number() protoreflect.EnumNumber {
	return protoreflect.EnumNumber(x)
}

// Deprecated: Use Role.Descriptor instead.
func (Role) EnumDescriptor() ([]byte, []int) {
	return file_pkg_lmproxyproto_cmd_proto_rawDescGZIP(), []int{1}
}

type ClusterState int32

const (
	ClusterState_WaitReady ClusterState = 0
	ClusterState_Ready     ClusterState = 1
	ClusterState_Migration ClusterState = 2
)

// Enum value maps for ClusterState.
var (
	ClusterState_name = map[int32]string{
		0: "WaitReady",
		1: "Ready",
		2: "Migration",
	}
	ClusterState_value = map[string]int32{
		"WaitReady": 0,
		"Ready":     1,
		"Migration": 2,
	}
)

func (x ClusterState) Enum() *ClusterState {
	p := new(ClusterState)
	*p = x
	return p
}

func (x ClusterState) String() string {
	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}

func (ClusterState) Descriptor() protoreflect.EnumDescriptor {
	return file_pkg_lmproxyproto_cmd_proto_enumTypes[2].Descriptor()
}

func (ClusterState) Type() protoreflect.EnumType {
	return &file_pkg_lmproxyproto_cmd_proto_enumTypes[2]
}

func (x ClusterState) Number() protoreflect.EnumNumber {
	return protoreflect.EnumNumber(x)
}

// Deprecated: Use ClusterState.Descriptor instead.
func (ClusterState) EnumDescriptor() ([]byte, []int) {
	return file_pkg_lmproxyproto_cmd_proto_rawDescGZIP(), []int{2}
}

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

	NodeID       int32  `protobuf:"varint,1,opt,name=nodeID,proto3" json:"nodeID,omitempty"`            // 节点ID
	NodeRaftAddr string `protobuf:"bytes,2,opt,name=nodeRaftAddr,proto3" json:"nodeRaftAddr,omitempty"` // 节点Raft地址
	NodeAPIAddr  string `protobuf:"bytes,3,opt,name=nodeAPIAddr,proto3" json:"nodeAPIAddr,omitempty"`   // api地址 类似 http://xxx.xxx.xxx.xxx:8080
	NodeRPCAddr  string `protobuf:"bytes,4,opt,name=nodeRPCAddr,proto3" json:"nodeRPCAddr,omitempty"`   // 节点RPC通讯地址
	TcpAddr      string `protobuf:"bytes,5,opt,name=tcpAddr,proto3" json:"tcpAddr,omitempty"`           // 节点tcp对外地址
	WsAddr       string `protobuf:"bytes,6,opt,name=wsAddr,proto3" json:"wsAddr,omitempty"`             // 节点websocket对外地址
	Role         Role   `protobuf:"varint,7,opt,name=role,proto3,enum=Role" json:"role,omitempty"`
	Join         bool   `protobuf:"varint,8,opt,name=join,proto3" json:"join,omitempty"` // 是否是新加入的节点
}

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

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

func (*Node) ProtoMessage() {}

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

func (x *Node) GetNodeID() int32 {
	if x != nil {
		return x.NodeID
	}
	return 0
}

func (x *Node) GetNodeRaftAddr() string {
	if x != nil {
		return x.NodeRaftAddr
	}
	return ""
}

func (x *Node) GetNodeAPIAddr() string {
	if x != nil {
		return x.NodeAPIAddr
	}
	return ""
}

func (x *Node) GetNodeRPCAddr() string {
	if x != nil {
		return x.NodeRPCAddr
	}
	return ""
}

func (x *Node) GetTcpAddr() string {
	if x != nil {
		return x.TcpAddr
	}
	return ""
}

func (x *Node) GetWsAddr() string {
	if x != nil {
		return x.WsAddr
	}
	return ""
}

func (x *Node) GetRole() Role {
	if x != nil {
		return x.Role
	}
	return Role_Unknown
}

func (x *Node) GetJoin() bool {
	if x != nil {
		return x.Join
	}
	return false
}

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

	NodeID int32 `protobuf:"varint,1,opt,name=nodeID,proto3" json:"nodeID,omitempty"` // 节点ID
}

func (x *ConnectReq) Reset() {
	*x = ConnectReq{}
	if protoimpl.UnsafeEnabled {
		mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[1]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

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

func (*ConnectReq) ProtoMessage() {}

func (x *ConnectReq) ProtoReflect() protoreflect.Message {
	mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[1]
	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 ConnectReq.ProtoReflect.Descriptor instead.
func (*ConnectReq) Descriptor() ([]byte, []int) {
	return file_pkg_lmproxyproto_cmd_proto_rawDescGZIP(), []int{1}
}

func (x *ConnectReq) GetNodeID() int32 {
	if x != nil {
		return x.NodeID
	}
	return 0
}

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

	Status      Status       `protobuf:"varint,1,opt,name=status,proto3,enum=Status" json:"status,omitempty"` // 状态 0.失败 1.成功
	Reason      string       `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"`              // 原因
	ProxyConfig *ProxyConfig `protobuf:"bytes,3,opt,name=proxyConfig,proto3" json:"proxyConfig,omitempty"`
}

func (x *ConnectResp) Reset() {
	*x = ConnectResp{}
	if protoimpl.UnsafeEnabled {
		mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[2]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

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

func (*ConnectResp) ProtoMessage() {}

func (x *ConnectResp) ProtoReflect() protoreflect.Message {
	mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[2]
	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 ConnectResp.ProtoReflect.Descriptor instead.
func (*ConnectResp) Descriptor() ([]byte, []int) {
	return file_pkg_lmproxyproto_cmd_proto_rawDescGZIP(), []int{2}
}

func (x *ConnectResp) GetStatus() Status {
	if x != nil {
		return x.Status
	}
	return Status_Error
}

func (x *ConnectResp) GetReason() string {
	if x != nil {
		return x.Reason
	}
	return ""
}

func (x *ConnectResp) GetProxyConfig() *ProxyConfig {
	if x != nil {
		return x.ProxyConfig
	}
	return nil
}

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

	UploadSlotBackupURL  string `protobuf:"bytes,1,opt,name=uploadSlotBackupURL,proto3" json:"uploadSlotBackupURL,omitempty"`   // 上传slot的url地址
	DowloadSlotBackupURL string `protobuf:"bytes,2,opt,name=dowloadSlotBackupURL,proto3" json:"dowloadSlotBackupURL,omitempty"` // 下载slot备份的地址
	RemoveSlotBackupURL  string `protobuf:"bytes,3,opt,name=removeSlotBackupURL,proto3" json:"removeSlotBackupURL,omitempty"`   // 移除slot备份的地址
}

func (x *ProxyConfig) Reset() {
	*x = ProxyConfig{}
	if protoimpl.UnsafeEnabled {
		mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[3]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

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

func (*ProxyConfig) ProtoMessage() {}

func (x *ProxyConfig) ProtoReflect() protoreflect.Message {
	mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[3]
	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 ProxyConfig.ProtoReflect.Descriptor instead.
func (*ProxyConfig) Descriptor() ([]byte, []int) {
	return file_pkg_lmproxyproto_cmd_proto_rawDescGZIP(), []int{3}
}

func (x *ProxyConfig) GetUploadSlotBackupURL() string {
	if x != nil {
		return x.UploadSlotBackupURL
	}
	return ""
}

func (x *ProxyConfig) GetDowloadSlotBackupURL() string {
	if x != nil {
		return x.DowloadSlotBackupURL
	}
	return ""
}

func (x *ProxyConfig) GetRemoveSlotBackupURL() string {
	if x != nil {
		return x.RemoveSlotBackupURL
	}
	return ""
}

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

	NodeID    int32 `protobuf:"varint,1,opt,name=nodeID,proto3" json:"nodeID,omitempty"`       // 节点ID
	ClusterID int32 `protobuf:"varint,2,opt,name=clusterID,proto3" json:"clusterID,omitempty"` // 分布式ID
}

func (x *ConnectInfo) Reset() {
	*x = ConnectInfo{}
	if protoimpl.UnsafeEnabled {
		mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[4]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

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

func (*ConnectInfo) ProtoMessage() {}

func (x *ConnectInfo) ProtoReflect() protoreflect.Message {
	mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[4]
	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 ConnectInfo.ProtoReflect.Descriptor instead.
func (*ConnectInfo) Descriptor() ([]byte, []int) {
	return file_pkg_lmproxyproto_cmd_proto_rawDescGZIP(), []int{4}
}

func (x *ConnectInfo) GetNodeID() int32 {
	if x != nil {
		return x.NodeID
	}
	return 0
}

func (x *ConnectInfo) GetClusterID() int32 {
	if x != nil {
		return x.ClusterID
	}
	return 0
}

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

	ClusterID int32 `protobuf:"varint,3,opt,name=clusterID,proto3" json:"clusterID,omitempty"`
}

func (x *ClusterConfigReq) Reset() {
	*x = ClusterConfigReq{}
	if protoimpl.UnsafeEnabled {
		mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[5]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

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

func (*ClusterConfigReq) ProtoMessage() {}

func (x *ClusterConfigReq) ProtoReflect() protoreflect.Message {
	mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[5]
	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 ClusterConfigReq.ProtoReflect.Descriptor instead.
func (*ClusterConfigReq) Descriptor() ([]byte, []int) {
	return file_pkg_lmproxyproto_cmd_proto_rawDescGZIP(), []int{5}
}

func (x *ClusterConfigReq) GetClusterID() int32 {
	if x != nil {
		return x.ClusterID
	}
	return 0
}

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

	Version         int32         `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"`                 // 配置版本
	SlotCount       int32         `protobuf:"varint,2,opt,name=slotCount,proto3" json:"slotCount,omitempty"`             // slot 总数量
	ClusterID       int32         `protobuf:"varint,3,opt,name=clusterID,proto3" json:"clusterID,omitempty"`             // cluster id
	Replica         int32         `protobuf:"varint,4,opt,name=replica,proto3" json:"replica,omitempty"`                 // 副本数
	State           ClusterState  `protobuf:"varint,5,opt,name=state,proto3,enum=ClusterState" json:"state,omitempty"`   // 状态
	Slots           []byte        `protobuf:"bytes,6,opt,name=slots,proto3" json:"slots,omitempty"`                      // slot bitmap
	Nodes           []*Node       `protobuf:"bytes,7,rep,name=nodes,proto3" json:"nodes,omitempty"`                      // 节点信息
	LeaderID        int32         `protobuf:"varint,8,opt,name=leaderID,proto3" json:"leaderID,omitempty"`               // 领导节点的id
	ImportClusterID int32         `protobuf:"varint,9,opt,name=importClusterID,proto3" json:"importClusterID,omitempty"` // 要导入的分布式ID
	ImportWill      []byte        `protobuf:"bytes,10,opt,name=importWill,proto3" json:"importWill,omitempty"`           // 将要引入的slots
	ExportWill      []byte        `protobuf:"bytes,11,opt,name=exportWill,proto3" json:"exportWill,omitempty"`           // 将要导出的slots
	Exporting       []byte        `protobuf:"bytes,12,opt,name=exporting,proto3" json:"exporting,omitempty"`             // 正在导出的slot（正在导出的slot将被锁定，不接受数据）
	ExportedList    *ExportedList `protobuf:"bytes,13,opt,name=exportedList,proto3" json:"exportedList,omitempty"`       // 已导出的slot
	Weight          int32         `protobuf:"varint,14,opt,name=weight,proto3" json:"weight,omitempty"`                  // 权重
}

func (x *ClusterConfig) Reset() {
	*x = ClusterConfig{}
	if protoimpl.UnsafeEnabled {
		mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[6]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

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

func (*ClusterConfig) ProtoMessage() {}

func (x *ClusterConfig) ProtoReflect() protoreflect.Message {
	mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[6]
	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 ClusterConfig.ProtoReflect.Descriptor instead.
func (*ClusterConfig) Descriptor() ([]byte, []int) {
	return file_pkg_lmproxyproto_cmd_proto_rawDescGZIP(), []int{6}
}

func (x *ClusterConfig) GetVersion() int32 {
	if x != nil {
		return x.Version
	}
	return 0
}

func (x *ClusterConfig) GetSlotCount() int32 {
	if x != nil {
		return x.SlotCount
	}
	return 0
}

func (x *ClusterConfig) GetClusterID() int32 {
	if x != nil {
		return x.ClusterID
	}
	return 0
}

func (x *ClusterConfig) GetReplica() int32 {
	if x != nil {
		return x.Replica
	}
	return 0
}

func (x *ClusterConfig) GetState() ClusterState {
	if x != nil {
		return x.State
	}
	return ClusterState_WaitReady
}

func (x *ClusterConfig) GetSlots() []byte {
	if x != nil {
		return x.Slots
	}
	return nil
}

func (x *ClusterConfig) GetNodes() []*Node {
	if x != nil {
		return x.Nodes
	}
	return nil
}

func (x *ClusterConfig) GetLeaderID() int32 {
	if x != nil {
		return x.LeaderID
	}
	return 0
}

func (x *ClusterConfig) GetImportClusterID() int32 {
	if x != nil {
		return x.ImportClusterID
	}
	return 0
}

func (x *ClusterConfig) GetImportWill() []byte {
	if x != nil {
		return x.ImportWill
	}
	return nil
}

func (x *ClusterConfig) GetExportWill() []byte {
	if x != nil {
		return x.ExportWill
	}
	return nil
}

func (x *ClusterConfig) GetExporting() []byte {
	if x != nil {
		return x.Exporting
	}
	return nil
}

func (x *ClusterConfig) GetExportedList() *ExportedList {
	if x != nil {
		return x.ExportedList
	}
	return nil
}

func (x *ClusterConfig) GetWeight() int32 {
	if x != nil {
		return x.Weight
	}
	return 0
}

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

	ClusterConfigs []*ClusterConfig `protobuf:"bytes,1,rep,name=clusterConfigs,proto3" json:"clusterConfigs,omitempty"`
}

func (x *ClusterConfigListResp) Reset() {
	*x = ClusterConfigListResp{}
	if protoimpl.UnsafeEnabled {
		mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[7]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

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

func (*ClusterConfigListResp) ProtoMessage() {}

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

func (x *ClusterConfigListResp) GetClusterConfigs() []*ClusterConfig {
	if x != nil {
		return x.ClusterConfigs
	}
	return nil
}

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

	No    string `protobuf:"bytes,1,opt,name=no,proto3" json:"no,omitempty"`
	Slots []byte `protobuf:"bytes,2,opt,name=slots,proto3" json:"slots,omitempty"` // 已导出的slots
	Path  string `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"`   // 对应的备份路径
}

func (x *Exported) Reset() {
	*x = Exported{}
	if protoimpl.UnsafeEnabled {
		mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[8]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

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

func (*Exported) ProtoMessage() {}

func (x *Exported) ProtoReflect() protoreflect.Message {
	mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[8]
	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 Exported.ProtoReflect.Descriptor instead.
func (*Exported) Descriptor() ([]byte, []int) {
	return file_pkg_lmproxyproto_cmd_proto_rawDescGZIP(), []int{8}
}

func (x *Exported) GetNo() string {
	if x != nil {
		return x.No
	}
	return ""
}

func (x *Exported) GetSlots() []byte {
	if x != nil {
		return x.Slots
	}
	return nil
}

func (x *Exported) GetPath() string {
	if x != nil {
		return x.Path
	}
	return ""
}

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

	Exported []*Exported `protobuf:"bytes,1,rep,name=exported,proto3" json:"exported,omitempty"`
}

func (x *ExportedList) Reset() {
	*x = ExportedList{}
	if protoimpl.UnsafeEnabled {
		mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[9]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

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

func (*ExportedList) ProtoMessage() {}

func (x *ExportedList) ProtoReflect() protoreflect.Message {
	mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[9]
	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 ExportedList.ProtoReflect.Descriptor instead.
func (*ExportedList) Descriptor() ([]byte, []int) {
	return file_pkg_lmproxyproto_cmd_proto_rawDescGZIP(), []int{9}
}

func (x *ExportedList) GetExported() []*Exported {
	if x != nil {
		return x.Exported
	}
	return nil
}

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

	Slots []byte `protobuf:"bytes,1,opt,name=slots,proto3" json:"slots,omitempty"` // 导出中的slots
}

func (x *Exporting) Reset() {
	*x = Exporting{}
	if protoimpl.UnsafeEnabled {
		mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[10]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

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

func (*Exporting) ProtoMessage() {}

func (x *Exporting) ProtoReflect() protoreflect.Message {
	mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[10]
	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 Exporting.ProtoReflect.Descriptor instead.
func (*Exporting) Descriptor() ([]byte, []int) {
	return file_pkg_lmproxyproto_cmd_proto_rawDescGZIP(), []int{10}
}

func (x *Exporting) GetSlots() []byte {
	if x != nil {
		return x.Slots
	}
	return nil
}

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

	No    string `protobuf:"bytes,1,opt,name=no,proto3" json:"no,omitempty"`
	Slots []byte `protobuf:"bytes,2,opt,name=slots,proto3" json:"slots,omitempty"` // 已导入的slots
}

func (x *Imported) Reset() {
	*x = Imported{}
	if protoimpl.UnsafeEnabled {
		mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[11]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

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

func (*Imported) ProtoMessage() {}

func (x *Imported) ProtoReflect() protoreflect.Message {
	mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[11]
	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 Imported.ProtoReflect.Descriptor instead.
func (*Imported) Descriptor() ([]byte, []int) {
	return file_pkg_lmproxyproto_cmd_proto_rawDescGZIP(), []int{11}
}

func (x *Imported) GetNo() string {
	if x != nil {
		return x.No
	}
	return ""
}

func (x *Imported) GetSlots() []byte {
	if x != nil {
		return x.Slots
	}
	return nil
}

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

	Version int32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` // 配置版本
}

func (x *ClusterConfigResp) Reset() {
	*x = ClusterConfigResp{}
	if protoimpl.UnsafeEnabled {
		mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[12]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

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

func (*ClusterConfigResp) ProtoMessage() {}

func (x *ClusterConfigResp) ProtoReflect() protoreflect.Message {
	mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[12]
	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 ClusterConfigResp.ProtoReflect.Descriptor instead.
func (*ClusterConfigResp) Descriptor() ([]byte, []int) {
	return file_pkg_lmproxyproto_cmd_proto_rawDescGZIP(), []int{12}
}

func (x *ClusterConfigResp) GetVersion() int32 {
	if x != nil {
		return x.Version
	}
	return 0
}

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

	ClusterID int32 `protobuf:"varint,1,opt,name=clusterID,proto3" json:"clusterID,omitempty"`
	Version   int32 `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty"`
}

func (x *ClusterConfigChange) Reset() {
	*x = ClusterConfigChange{}
	if protoimpl.UnsafeEnabled {
		mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[13]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

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

func (*ClusterConfigChange) ProtoMessage() {}

func (x *ClusterConfigChange) ProtoReflect() protoreflect.Message {
	mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[13]
	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 ClusterConfigChange.ProtoReflect.Descriptor instead.
func (*ClusterConfigChange) Descriptor() ([]byte, []int) {
	return file_pkg_lmproxyproto_cmd_proto_rawDescGZIP(), []int{13}
}

func (x *ClusterConfigChange) GetClusterID() int32 {
	if x != nil {
		return x.ClusterID
	}
	return 0
}

func (x *ClusterConfigChange) GetVersion() int32 {
	if x != nil {
		return x.Version
	}
	return 0
}

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

	Version      int32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"`           //配置版本
	ClusterID    int32 `protobuf:"varint,2,opt,name=clusterID,proto3" json:"clusterID,omitempty"`       // 分布式ID
	LeaderID     int32 `protobuf:"varint,3,opt,name=leaderID,proto3" json:"leaderID,omitempty"`         // 领导ID
	TotalVersion int32 `protobuf:"varint,4,opt,name=totalVersion,proto3" json:"totalVersion,omitempty"` // 所有分布式配置的总版本（集群内的所有clusterConfig的version累加的值）
}

func (x *Ping) Reset() {
	*x = Ping{}
	if protoimpl.UnsafeEnabled {
		mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[14]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

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

func (*Ping) ProtoMessage() {}

func (x *Ping) ProtoReflect() protoreflect.Message {
	mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[14]
	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 Ping.ProtoReflect.Descriptor instead.
func (*Ping) Descriptor() ([]byte, []int) {
	return file_pkg_lmproxyproto_cmd_proto_rawDescGZIP(), []int{14}
}

func (x *Ping) GetVersion() int32 {
	if x != nil {
		return x.Version
	}
	return 0
}

func (x *Ping) GetClusterID() int32 {
	if x != nil {
		return x.ClusterID
	}
	return 0
}

func (x *Ping) GetLeaderID() int32 {
	if x != nil {
		return x.LeaderID
	}
	return 0
}

func (x *Ping) GetTotalVersion() int32 {
	if x != nil {
		return x.TotalVersion
	}
	return 0
}

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

	Status    Status `protobuf:"varint,1,opt,name=status,proto3,enum=Status" json:"status,omitempty"` // 状态 0.失败 1.成功
	Reason    string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"`              // 原因
	ClusterID int32  `protobuf:"varint,3,opt,name=clusterID,proto3" json:"clusterID,omitempty"`       // 分布式ID
}

func (x *RegisterNodeResp) Reset() {
	*x = RegisterNodeResp{}
	if protoimpl.UnsafeEnabled {
		mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[15]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

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

func (*RegisterNodeResp) ProtoMessage() {}

func (x *RegisterNodeResp) ProtoReflect() protoreflect.Message {
	mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[15]
	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 RegisterNodeResp.ProtoReflect.Descriptor instead.
func (*RegisterNodeResp) Descriptor() ([]byte, []int) {
	return file_pkg_lmproxyproto_cmd_proto_rawDescGZIP(), []int{15}
}

func (x *RegisterNodeResp) GetStatus() Status {
	if x != nil {
		return x.Status
	}
	return Status_Error
}

func (x *RegisterNodeResp) GetReason() string {
	if x != nil {
		return x.Reason
	}
	return ""
}

func (x *RegisterNodeResp) GetClusterID() int32 {
	if x != nil {
		return x.ClusterID
	}
	return 0
}

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

	Status Status `protobuf:"varint,1,opt,name=status,proto3,enum=Status" json:"status,omitempty"` // 状态 0.失败 1.成功
	Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"`              // 原因
}

func (x *StatusResp) Reset() {
	*x = StatusResp{}
	if protoimpl.UnsafeEnabled {
		mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[16]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

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

func (*StatusResp) ProtoMessage() {}

func (x *StatusResp) ProtoReflect() protoreflect.Message {
	mi := &file_pkg_lmproxyproto_cmd_proto_msgTypes[16]
	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 StatusResp.ProtoReflect.Descriptor instead.
func (*StatusResp) Descriptor() ([]byte, []int) {
	return file_pkg_lmproxyproto_cmd_proto_rawDescGZIP(), []int{16}
}

func (x *StatusResp) GetStatus() Status {
	if x != nil {
		return x.Status
	}
	return Status_Error
}

func (x *StatusResp) GetReason() string {
	if x != nil {
		return x.Reason
	}
	return ""
}

var File_pkg_lmproxyproto_cmd_proto protoreflect.FileDescriptor

var file_pkg_lmproxyproto_cmd_proto_rawDesc = []byte{
	0x0a, 0x1a, 0x70, 0x6b, 0x67, 0x2f, 0x6c, 0x6d, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x70, 0x72, 0x6f,
	0x74, 0x6f, 0x2f, 0x63, 0x6d, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe7, 0x01, 0x0a,
	0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x44, 0x18,
	0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x44, 0x12, 0x22, 0x0a,
	0x0c, 0x6e, 0x6f, 0x64, 0x65, 0x52, 0x61, 0x66, 0x74, 0x41, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20,
	0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x6f, 0x64, 0x65, 0x52, 0x61, 0x66, 0x74, 0x41, 0x64, 0x64,
	0x72, 0x12, 0x20, 0x0a, 0x0b, 0x6e, 0x6f, 0x64, 0x65, 0x41, 0x50, 0x49, 0x41, 0x64, 0x64, 0x72,
	0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x6f, 0x64, 0x65, 0x41, 0x50, 0x49, 0x41,
	0x64, 0x64, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x6e, 0x6f, 0x64, 0x65, 0x52, 0x50, 0x43, 0x41, 0x64,
	0x64, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x6f, 0x64, 0x65, 0x52, 0x50,
	0x43, 0x41, 0x64, 0x64, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x63, 0x70, 0x41, 0x64, 0x64, 0x72,
	0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x63, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12,
	0x16, 0x0a, 0x06, 0x77, 0x73, 0x41, 0x64, 0x64, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,
	0x06, 0x77, 0x73, 0x41, 0x64, 0x64, 0x72, 0x12, 0x19, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18,
	0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x05, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f,
	0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6a, 0x6f, 0x69, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08,
	0x52, 0x04, 0x6a, 0x6f, 0x69, 0x6e, 0x22, 0x24, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
	0x74, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x44, 0x18, 0x01,
	0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x44, 0x22, 0x76, 0x0a, 0x0b,
	0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1f, 0x0a, 0x06, 0x73,
	0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x07, 0x2e, 0x53, 0x74,
	0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06,
	0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65,
	0x61, 0x73, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f, 0x6e,
	0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x50, 0x72, 0x6f, 0x78,
	0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f,
	0x6e, 0x66, 0x69, 0x67, 0x22, 0xa5, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f,
	0x6e, 0x66, 0x69, 0x67, 0x12, 0x30, 0x0a, 0x13, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x6c,
	0x6f, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x55, 0x52, 0x4c, 0x18, 0x01, 0x20, 0x01, 0x28,
	0x09, 0x52, 0x13, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x6c, 0x6f, 0x74, 0x42, 0x61, 0x63,
	0x6b, 0x75, 0x70, 0x55, 0x52, 0x4c, 0x12, 0x32, 0x0a, 0x14, 0x64, 0x6f, 0x77, 0x6c, 0x6f, 0x61,
	0x64, 0x53, 0x6c, 0x6f, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x55, 0x52, 0x4c, 0x18, 0x02,
	0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x64, 0x6f, 0x77, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x6c, 0x6f,
	0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x55, 0x52, 0x4c, 0x12, 0x30, 0x0a, 0x13, 0x72, 0x65,
	0x6d, 0x6f, 0x76, 0x65, 0x53, 0x6c, 0x6f, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x55, 0x52,
	0x4c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53,
	0x6c, 0x6f, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x55, 0x52, 0x4c, 0x22, 0x43, 0x0a, 0x0b,
	0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x6e,
	0x6f, 0x64, 0x65, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6e, 0x6f, 0x64,
	0x65, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44,
	0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49,
	0x44, 0x22, 0x30, 0x0a, 0x10, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66,
	0x69, 0x67, 0x52, 0x65, 0x71, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
	0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65,
	0x72, 0x49, 0x44, 0x22, 0xc6, 0x03, 0x0a, 0x0d, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43,
	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
	0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12,
	0x1c, 0x0a, 0x09, 0x73, 0x6c, 0x6f, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01,
	0x28, 0x05, 0x52, 0x09, 0x73, 0x6c, 0x6f, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1c, 0x0a,
	0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05,
	0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x72,
	0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x72, 0x65,
	0x70, 0x6c, 0x69, 0x63, 0x61, 0x12, 0x23, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x05,
	0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x53, 0x74,
	0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x6c,
	0x6f, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x6c, 0x6f, 0x74, 0x73,
	0x12, 0x1b, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32,
	0x05, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x1a, 0x0a,
	0x08, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x49, 0x44, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52,
	0x08, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x49, 0x44, 0x12, 0x28, 0x0a, 0x0f, 0x69, 0x6d, 0x70,
	0x6f, 0x72, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x09, 0x20, 0x01,
	0x28, 0x05, 0x52, 0x0f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65,
	0x72, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x57, 0x69, 0x6c,
	0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x57,
	0x69, 0x6c, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x57, 0x69, 0x6c,
	0x6c, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x57,
	0x69, 0x6c, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67,
	0x18, 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e,
	0x67, 0x12, 0x31, 0x0a, 0x0c, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4c, 0x69, 0x73,
	0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74,
	0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x0c, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64,
	0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x0e,
	0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x4f, 0x0a, 0x15,
	0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x69, 0x73,
	0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x36, 0x0a, 0x0e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e,
	0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x63,
	0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22, 0x44, 0x0a,
	0x08, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x6e, 0x6f, 0x18,
	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x6e, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x6c, 0x6f,
	0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x6c, 0x6f, 0x74, 0x73, 0x12,
	0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70,
	0x61, 0x74, 0x68, 0x22, 0x35, 0x0a, 0x0c, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4c,
	0x69, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x08, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18,
	0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64,
	0x52, 0x08, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x22, 0x21, 0x0a, 0x09, 0x45, 0x78,
	0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x6c, 0x6f, 0x74, 0x73,
	0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x6c, 0x6f, 0x74, 0x73, 0x22, 0x30, 0x0a,
	0x08, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x6e, 0x6f, 0x18,
	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x6e, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x6c, 0x6f,
	0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x6c, 0x6f, 0x74, 0x73, 0x22,
	0x2d, 0x0a, 0x11, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
	0x52, 0x65, 0x73, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18,
	0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x4d,
	0x0a, 0x13, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x43,
	0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
	0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65,
	0x72, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02,
	0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x7e, 0x0a,
	0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
	0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12,
	0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01,
	0x28, 0x05, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12, 0x1a, 0x0a,
	0x08, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52,
	0x08, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x0c, 0x74, 0x6f, 0x74,
	0x61, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52,
	0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x69, 0x0a,
	0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73,
	0x70, 0x12, 0x1f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
	0x0e, 0x32, 0x07, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74,
	0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01,
	0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c,
	0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x63,
	0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x22, 0x45, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74,
	0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
	0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x07, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
	0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f,
	0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x2a,
	0x20, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x72, 0x72,
	0x6f, 0x72, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x10,
	0x01, 0x2a, 0x2a, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b,
	0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72,
	0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x6c, 0x61, 0x76, 0x65, 0x10, 0x02, 0x2a, 0x37, 0x0a,
	0x0c, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0d, 0x0a,
	0x09, 0x57, 0x61, 0x69, 0x74, 0x52, 0x65, 0x61, 0x64, 0x79, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05,
	0x52, 0x65, 0x61, 0x64, 0x79, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4d, 0x69, 0x67, 0x72, 0x61,
	0x74, 0x69, 0x6f, 0x6e, 0x10, 0x02, 0x42, 0x11, 0x5a, 0x0f, 0x2e, 0x2f, 0x3b, 0x6c, 0x6d, 0x70,
	0x72, 0x6f, 0x78, 0x79, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
	0x33,
}

var (
	file_pkg_lmproxyproto_cmd_proto_rawDescOnce sync.Once
	file_pkg_lmproxyproto_cmd_proto_rawDescData = file_pkg_lmproxyproto_cmd_proto_rawDesc
)

func file_pkg_lmproxyproto_cmd_proto_rawDescGZIP() []byte {
	file_pkg_lmproxyproto_cmd_proto_rawDescOnce.Do(func() {
		file_pkg_lmproxyproto_cmd_proto_rawDescData = protoimpl.X.CompressGZIP(file_pkg_lmproxyproto_cmd_proto_rawDescData)
	})
	return file_pkg_lmproxyproto_cmd_proto_rawDescData
}

var file_pkg_lmproxyproto_cmd_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
var file_pkg_lmproxyproto_cmd_proto_msgTypes = make([]protoimpl.MessageInfo, 17)
var file_pkg_lmproxyproto_cmd_proto_goTypes = []interface{}{
	(Status)(0),                   // 0: Status
	(Role)(0),                     // 1: Role
	(ClusterState)(0),             // 2: ClusterState
	(*Node)(nil),                  // 3: Node
	(*ConnectReq)(nil),            // 4: ConnectReq
	(*ConnectResp)(nil),           // 5: ConnectResp
	(*ProxyConfig)(nil),           // 6: ProxyConfig
	(*ConnectInfo)(nil),           // 7: ConnectInfo
	(*ClusterConfigReq)(nil),      // 8: ClusterConfigReq
	(*ClusterConfig)(nil),         // 9: ClusterConfig
	(*ClusterConfigListResp)(nil), // 10: ClusterConfigListResp
	(*Exported)(nil),              // 11: Exported
	(*ExportedList)(nil),          // 12: ExportedList
	(*Exporting)(nil),             // 13: Exporting
	(*Imported)(nil),              // 14: Imported
	(*ClusterConfigResp)(nil),     // 15: ClusterConfigResp
	(*ClusterConfigChange)(nil),   // 16: ClusterConfigChange
	(*Ping)(nil),                  // 17: Ping
	(*RegisterNodeResp)(nil),      // 18: RegisterNodeResp
	(*StatusResp)(nil),            // 19: StatusResp
}
var file_pkg_lmproxyproto_cmd_proto_depIdxs = []int32{
	1,  // 0: Node.role:type_name -> Role
	0,  // 1: ConnectResp.status:type_name -> Status
	6,  // 2: ConnectResp.proxyConfig:type_name -> ProxyConfig
	2,  // 3: ClusterConfig.state:type_name -> ClusterState
	3,  // 4: ClusterConfig.nodes:type_name -> Node
	12, // 5: ClusterConfig.exportedList:type_name -> ExportedList
	9,  // 6: ClusterConfigListResp.clusterConfigs:type_name -> ClusterConfig
	11, // 7: ExportedList.exported:type_name -> Exported
	0,  // 8: RegisterNodeResp.status:type_name -> Status
	0,  // 9: StatusResp.status:type_name -> Status
	10, // [10:10] is the sub-list for method output_type
	10, // [10:10] is the sub-list for method input_type
	10, // [10:10] is the sub-list for extension type_name
	10, // [10:10] is the sub-list for extension extendee
	0,  // [0:10] is the sub-list for field type_name
}

func init() { file_pkg_lmproxyproto_cmd_proto_init() }
func file_pkg_lmproxyproto_cmd_proto_init() {
	if File_pkg_lmproxyproto_cmd_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_pkg_lmproxyproto_cmd_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Node); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_pkg_lmproxyproto_cmd_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ConnectReq); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_pkg_lmproxyproto_cmd_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ConnectResp); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_pkg_lmproxyproto_cmd_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ProxyConfig); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_pkg_lmproxyproto_cmd_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ConnectInfo); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_pkg_lmproxyproto_cmd_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ClusterConfigReq); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_pkg_lmproxyproto_cmd_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ClusterConfig); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_pkg_lmproxyproto_cmd_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ClusterConfigListResp); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_pkg_lmproxyproto_cmd_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Exported); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_pkg_lmproxyproto_cmd_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ExportedList); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_pkg_lmproxyproto_cmd_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Exporting); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_pkg_lmproxyproto_cmd_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Imported); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_pkg_lmproxyproto_cmd_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ClusterConfigResp); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_pkg_lmproxyproto_cmd_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ClusterConfigChange); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_pkg_lmproxyproto_cmd_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Ping); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_pkg_lmproxyproto_cmd_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*RegisterNodeResp); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_pkg_lmproxyproto_cmd_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*StatusResp); 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_pkg_lmproxyproto_cmd_proto_rawDesc,
			NumEnums:      3,
			NumMessages:   17,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_pkg_lmproxyproto_cmd_proto_goTypes,
		DependencyIndexes: file_pkg_lmproxyproto_cmd_proto_depIdxs,
		EnumInfos:         file_pkg_lmproxyproto_cmd_proto_enumTypes,
		MessageInfos:      file_pkg_lmproxyproto_cmd_proto_msgTypes,
	}.Build()
	File_pkg_lmproxyproto_cmd_proto = out.File
	file_pkg_lmproxyproto_cmd_proto_rawDesc = nil
	file_pkg_lmproxyproto_cmd_proto_goTypes = nil
	file_pkg_lmproxyproto_cmd_proto_depIdxs = nil
}

license: MIT

license_type: permissive

branch_name: refs/heads/master

extension: go


text:
using System;
using System.Collections.Generic;
using System.Text;

namespace RockPaperSissors.Library.Difficulty
{
    public interface IDifficulty
    {
        string getMove();
    }
}

branch_name: refs/heads/main

extension: cs


text:
DESCRIPTION = "Extended task to get System Test specific apps"
LICENSE = "MIT"
PR = "r50"

PACKAGE_ARCH = "${MACHINE_ARCH}"

inherit packagegroup

ARAGO_TEST = "\
    bonnie++ \
    hdparm \
    iozone3 \
    lmbench \
    rt-tests \
    evtest \
    bc \
    memtester \
    libdrm-tests \
    powertop \
    stress \
    stress-ng \
    yavta \
    rng-tools \
    perf \
    v4l-utils \
    smcroute \
    rwmem \
    pulseaudio-misc \
    kselftests \
    cpuset \
    procps \
    mtd-utils-ubifs-tests \
    pcitest \
    mstpd \
    fio \
    "

ARAGO_TEST_append_armv7a = " \
    cpuburn-neon \
"

ARAGO_TEST_append_armv7ve = " \
    cpuburn-neon \
"

ARAGO_TI_TEST = " \
    ltp-ddt \
    input-utils \
    cpuloadgen \
    timestamping \
    uvc-gadget \
    "

ARAGO_TI_TEST_append_ti33x = " \
    omapconf \
    "

ARAGO_TI_TEST_append_ti43x = " \
    omapconf \
    "

ARAGO_TI_TEST_append_omap-a15 = " \
    omapconf \
    ti-ipc-test \
    "

ARAGO_TI_TEST_append_am65xx = " \
    ti-ipc-test \
    "

ARAGO_TI_TEST_append_j7-evm = " \
    viddec-test-app \
    videnc-test-app \
    ufs-tool \
    "

ARAGO_TI_TEST_append_keystone = " \
    ti-ipc-test \
    "

ARAGO_TI_TEST_append_omapl138 = " \
    ti-ipc-test \
    "

RDEPENDS_${PN} = "\
    ${ARAGO_TEST} \
    ${ARAGO_TI_TEST} \
    "

extension: bb


text:
#pragma once

#include "SpawnArea.h"

class FishmanSpawnArea : public SpawnArea
{
public:
	FishmanSpawnArea(ObjectFactory& objectFactory);

private:
	void SpawnObject(UpdateData& updateData) override;
};

repository: warzes/Soulvania

repo_name: warzes/Soulvania


text:
using Calendar001.Src;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Calendar001.Controller
{
    class LoadMemoManager
    {
        private static readonly int[] numberOfDays = new int[13] { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

        /// <summary>
        /// 해당하는 날짜를 불러옵니다.
        /// </summary>
        /// <param name="selectedTime"></param>
        /// <param name="day"></param>
        /// <param name="memo"></param>
        private DailyMemo LoadDay(DateTime selectedTime, int day, string memo)
        {
            DailyMemo newDaysItem = new DailyMemo(selectedTime.Year, selectedTime.Month, day);
            newDaysItem.SetMemo(memo);
            newDaysItem.SetMemoFont();

            return newDaysItem;
        }

        /// <summary>
        /// 인자로 받은 년, 월에 맞게 달을 불러옵니다.
        /// </summary>
        /// <param name="selectedTime">the selectedTime you want to load</param>
        public List<DailyMemo> LoadMonth(DateTime selectedTime)
        {
            int year = selectedTime.Year;
            int month = selectedTime.Month;
            DateTime now = DateTime.Now;
            List<DailyMemo> dailyMemos = new List<DailyMemo>();

            int countDays = numberOfDays[month];
            Dictionary<DateTime, Memo> loadedMemos = MemoManager.Instance.GetMemos(year, month);

            // 2월의 경우, 윤년이면 1을 더해줍니다.
            countDays += month == 2 && year % 4 == 0 ? 1 : 0;

            for (int day = 1; day <= countDays; day++)
            {
                string memo = "";
                DateTime currentDate = new DateTime(year, month, day);
                if (loadedMemos.ContainsKey(currentDate))
                {
                    memo = loadedMemos[currentDate].Content.ToString();
                }
                DailyMemo newDay = LoadDay(selectedTime, day, memo);
                dailyMemos.Add(newDay);

                // 해당 날짜가 오늘이면 하이라이팅한다.
                if (now.Day == day && now.Month == month && now.Year == year)
                {
                    newDay.ShowBorder();
                }
            }
            return dailyMemos;
        }
    }
}