feature support generate message
This commit is contained in:
commit
b1a44a46da
72
.clang-format
Normal file
72
.clang-format
Normal file
@ -0,0 +1,72 @@
|
||||
# Generated from CLion C/C++ Code Style settings
|
||||
BinPackParameters: false
|
||||
BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: None
|
||||
AlignOperands: DontAlign
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowAllConstructorInitializersOnNextLine: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: Always
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: true
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
# 函数和返回类型分两行,方便阅读
|
||||
AlwaysBreakAfterReturnType: TopLevelDefinitions
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: true
|
||||
BreakBeforeBinaryOperators: NonAssignment
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
BreakInheritanceList: BeforeColon
|
||||
ColumnLimit: 120
|
||||
CompactNamespaces: false
|
||||
ContinuationIndentWidth: 4
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
SeparateDefinitionBlocks: Always
|
||||
IndentCaseLabels: false
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: 4
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: false
|
||||
PointerAlignment: Right
|
||||
ReflowComments: false
|
||||
SortIncludes: Never
|
||||
SpaceAfterCStyleCast: true
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 0
|
||||
SpacesInAngles: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
.idea/
|
||||
cmake-build-*
|
||||
build/
|
||||
*gen*/
|
21
CMakeLists.txt
Normal file
21
CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
||||
cmake_minimum_required(VERSION 3.26)
|
||||
project(crpc)
|
||||
|
||||
find_package(antlr4-runtime CONFIG REQUIRED)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
FILE(GLOB_RECURSE SRC_LIST ${PROJECT_SOURCE_DIR}/src/*.cpp)
|
||||
add_executable(crpc
|
||||
main.cpp
|
||||
src/item.cpp
|
||||
src/message.cpp
|
||||
${SRC_LIST}
|
||||
src/rpc.cpp
|
||||
src/service.cpp
|
||||
src/plugins/c/c_message_plugin.cpp
|
||||
)
|
||||
target_link_libraries(crpc PRIVATE antlr4_static)
|
||||
target_include_directories(crpc PRIVATE /opt/dev/vcpkg/installed/arm64-osx/include/antlr4-runtime)
|
||||
target_include_directories(crpc PRIVATE src/gen/ src/)
|
||||
|
101
main.cpp
Normal file
101
main.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
#include "antlr4-runtime.h"
|
||||
#include "ProtoParserBaseListener.h"
|
||||
#include "ProtoParserBaseVisitor.h"
|
||||
#include "ProtoLexer.h"
|
||||
#include "ProtoParser.h"
|
||||
#include "message.h"
|
||||
#include "service.h"
|
||||
#include "plugins/c/c_message_plugin.h"
|
||||
#include <stack>
|
||||
#include <map>
|
||||
|
||||
class Listener : public ProtoParserBaseListener {
|
||||
public:
|
||||
void enterMessageStatement(ProtoParser::MessageStatementContext *context) override
|
||||
{
|
||||
message_stack.push(std::make_shared<tqcq::Message>(context->ID()->getText()));
|
||||
}
|
||||
|
||||
void exitMessageStatement(ProtoParser::MessageStatementContext *context) override
|
||||
{
|
||||
message_stack.top()->SetItems(std::move(items));
|
||||
assert(items.empty());
|
||||
if (message_map.find(message_stack.top()->id()) != message_map.end()) {
|
||||
std::cout << "message " << message_stack.top()->id() << " already exists" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
message_map.insert(std::make_pair(message_stack.top()->id(), message_stack.top()));
|
||||
message_stack.pop();
|
||||
}
|
||||
|
||||
void exitItemStatement(ProtoParser::ItemStatementContext *context) override
|
||||
{
|
||||
int idx = std::stoi(context->NUMBER()->getText());
|
||||
tqcq::Item::Ptr item = nullptr;
|
||||
if (context->INT32()) {
|
||||
item = std::make_shared<tqcq::Item>(tqcq::Item::Type::kInt32, context->ID()->getText(), idx);
|
||||
} else if (context->STRING()){
|
||||
item = std::make_shared<tqcq::Item>(tqcq::Item::Type::kString, context->ID()->getText(), idx);
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
items.push_back(std::move(item));
|
||||
}
|
||||
|
||||
void exitServiceStatement(ProtoParser::ServiceStatementContext *context) override
|
||||
{
|
||||
std::string id = context->ID()->getText();
|
||||
auto service = std::make_shared<tqcq::Service>(id);
|
||||
service->SetRPCs(std::move(rpcs));
|
||||
assert(rpcs.empty());
|
||||
services.push_back(std::move(service));
|
||||
}
|
||||
|
||||
void exitRpcStatement(ProtoParser::RpcStatementContext *context) override {
|
||||
std::string id = context->ID(0)->getText();
|
||||
std::string request_id = context->ID(1)->getText();
|
||||
std::string response_id = context->ID(2)->getText();
|
||||
auto rpc = std::make_shared<tqcq::RPC>(id, request_id, response_id);
|
||||
rpcs.push_back(std::move(rpc));
|
||||
}
|
||||
|
||||
std::map<std::string, tqcq::Message::Ptr> message_map;
|
||||
std::vector<tqcq::Item::Ptr> items;
|
||||
std::stack<tqcq::Message::Ptr> message_stack;
|
||||
|
||||
std::vector<tqcq::RPC::Ptr> rpcs;
|
||||
std::vector<tqcq::Service::Ptr> services;
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
std::ifstream ifs;
|
||||
ifs.open(argv[1]);
|
||||
|
||||
antlr4::ANTLRInputStream input(ifs);
|
||||
ProtoLexer lexer(&input);
|
||||
antlr4::CommonTokenStream tokens(&lexer);
|
||||
ProtoParser parser(&tokens);
|
||||
// parser.removeErrorListeners();
|
||||
// Visitor visitor;
|
||||
// visitor.visit(parser.program());
|
||||
Listener listener;
|
||||
Listener listener2;
|
||||
antlr4::tree::ParseTreeWalker::DEFAULT.walk(&listener, parser.program());
|
||||
for (const auto& item : listener.message_map) {
|
||||
std::cout << item.second->ToString() << std::endl;
|
||||
}
|
||||
|
||||
for (const auto& service : listener.services) {
|
||||
std::cout << service->ToString() << std::endl;
|
||||
}
|
||||
|
||||
tqcq::CMessagePlugin message_plugin("/tmp/gen");
|
||||
message_plugin.Generate(listener.message_map);
|
||||
|
||||
return 0;
|
||||
}
|
27
src/ProtoLexer.g4
Normal file
27
src/ProtoLexer.g4
Normal file
@ -0,0 +1,27 @@
|
||||
lexer grammar ProtoLexer;
|
||||
|
||||
INT32: 'int32';
|
||||
STRING: 'string';
|
||||
|
||||
VERSION2: 'proto2';
|
||||
VERSION3: 'proto3';
|
||||
|
||||
SYNTAX_TYPE: 'syntax';
|
||||
MESSAGE_TYPE: 'message';
|
||||
RPC_TYPE: 'rpc';
|
||||
RETURNS_TYPE: 'returns';
|
||||
SERVICE_TYPE: 'service';
|
||||
|
||||
EQUAL: '=';
|
||||
SEMICOLON: ';';
|
||||
COMMA: ',';
|
||||
QUOTE: '"';
|
||||
OPEN_BRACE: '{';
|
||||
CLOSE_BRACE: '}';
|
||||
OPEN_PAREN: '(';
|
||||
CLOSE_PAREN: ')';
|
||||
|
||||
NUMBER: [0-9]+;
|
||||
ID: [a-zA-Z_][a-zA-Z_0-9]*;
|
||||
|
||||
WHITESPACE: [ \t\r\n]+ -> skip;
|
13
src/ProtoParser.g4
Normal file
13
src/ProtoParser.g4
Normal file
@ -0,0 +1,13 @@
|
||||
parser grammar ProtoParser;
|
||||
|
||||
options{ tokenVocab='gen/ProtoLexer'; language=Cpp; }
|
||||
|
||||
program: syntaxStatement baseStatement* EOF;
|
||||
|
||||
syntaxStatement: SYNTAX_TYPE '=' '"' (VERSION2 | VERSION3) '"' ';';
|
||||
baseStatement: (messageStatement | serviceStatement | ';');
|
||||
messageStatement: MESSAGE_TYPE ID '{' itemStatement* '}' ';';
|
||||
serviceStatement: SERVICE_TYPE ID '{' rpcStatement* '}' ';';
|
||||
|
||||
itemStatement: (INT32 | STRING) ID '=' NUMBER ';';
|
||||
rpcStatement: RPC_TYPE ID '(' ID ')' 'returns' '(' ID ')' ';';
|
50
src/item.cpp
Normal file
50
src/item.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
//
|
||||
// Created by tqcq on 2023/12/1.
|
||||
//
|
||||
|
||||
#include "item.h"
|
||||
|
||||
namespace tqcq {
|
||||
Item::Item(Item::Type type, std::string id, int idx)
|
||||
: type_(type),
|
||||
id_(std::move(id)),
|
||||
idx_(idx)
|
||||
{}
|
||||
|
||||
Item::Type
|
||||
Item::type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
std::string
|
||||
Item::id() const
|
||||
{
|
||||
return id_;
|
||||
}
|
||||
|
||||
int
|
||||
Item::idx() const
|
||||
{
|
||||
return idx_;
|
||||
}
|
||||
|
||||
std::string
|
||||
Item::ToString()
|
||||
{
|
||||
return ToString(type_) + " " + id_ + " = " + std::to_string(idx_)+ ";";
|
||||
}
|
||||
|
||||
std::string
|
||||
Item::ToString(Item::Type type)
|
||||
{
|
||||
switch(type) {
|
||||
case Item::Type::kInt32:
|
||||
return "int32";
|
||||
case Item::Type::kString:
|
||||
return "string";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
}// namespace tqcq
|
40
src/item.h
Normal file
40
src/item.h
Normal file
@ -0,0 +1,40 @@
|
||||
//
|
||||
// Created by tqcq on 2023/12/1.
|
||||
//
|
||||
|
||||
#ifndef CRPC_SRC_ITEM_H_
|
||||
#define CRPC_SRC_ITEM_H_
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
namespace tqcq {
|
||||
|
||||
class Item {
|
||||
public:
|
||||
enum class Type {
|
||||
kInt32,
|
||||
kString
|
||||
};
|
||||
static std::string ToString(Type type);
|
||||
|
||||
using Ptr = std::shared_ptr<Item>;
|
||||
|
||||
Item() = delete;
|
||||
Item(Type type, std::string id, int idx);
|
||||
virtual ~Item() = default;
|
||||
Type type() const;
|
||||
std::string id() const;
|
||||
int idx() const;
|
||||
|
||||
virtual std::string ToString();
|
||||
protected:
|
||||
private:
|
||||
Type type_;
|
||||
std::string id_;
|
||||
int idx_;
|
||||
};
|
||||
|
||||
}// namespace tqcq
|
||||
|
||||
#endif//CRPC_SRC_ITEM_H_
|
53
src/message.cpp
Normal file
53
src/message.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
//
|
||||
// Created by tqcq on 2023/12/1.
|
||||
//
|
||||
|
||||
#include "message.h"
|
||||
#include <sstream>
|
||||
|
||||
namespace tqcq {
|
||||
Message::Message(std::string id) : id_(id){}
|
||||
|
||||
std::string
|
||||
Message::id() const
|
||||
{
|
||||
return id_;
|
||||
}
|
||||
|
||||
void
|
||||
Message::AddItem(Item::Ptr item)
|
||||
{
|
||||
items_.push_back(std::move(item));
|
||||
}
|
||||
|
||||
std::vector<Item::Ptr>
|
||||
Message::items() const
|
||||
{
|
||||
return items_;
|
||||
}
|
||||
|
||||
void
|
||||
Message::SetItems(std::vector<Item::Ptr> items)
|
||||
{
|
||||
items_ = std::move(items);
|
||||
}
|
||||
|
||||
std::string
|
||||
Message::ToString()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "message " << id_ << " {";
|
||||
|
||||
for (const auto& item : items_) {
|
||||
ss << std::endl;
|
||||
ss << " " << item->ToString();
|
||||
}
|
||||
|
||||
if (!items_.empty()) {
|
||||
ss << std::endl;
|
||||
}
|
||||
|
||||
ss << "};";
|
||||
return ss.str();
|
||||
}
|
||||
}// namespace tqcq
|
38
src/message.h
Normal file
38
src/message.h
Normal file
@ -0,0 +1,38 @@
|
||||
//
|
||||
// Created by tqcq on 2023/12/1.
|
||||
//
|
||||
|
||||
#ifndef CRPC_SRC_MESSAGE_H_
|
||||
#define CRPC_SRC_MESSAGE_H_
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "item.h"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace tqcq {
|
||||
|
||||
class Message {
|
||||
public:
|
||||
using Ptr = std::shared_ptr<Message>;
|
||||
|
||||
Message(std::string id);
|
||||
std::string id() const;
|
||||
void AddItem(Item::Ptr item);
|
||||
void SetItems(std::vector<Item::Ptr> items);
|
||||
std::vector<Item::Ptr> items() const;
|
||||
void AddDependency(std::string dependency);
|
||||
void SetDependencies(std::set<std::string> dependencies);
|
||||
std::set<std::string> dependencies() const;
|
||||
|
||||
std::string ToString();
|
||||
private:
|
||||
std::string id_;
|
||||
std::vector<Item::Ptr> items_;
|
||||
std::set<std::string> dependencies_;
|
||||
};
|
||||
|
||||
}// namespace tqcq
|
||||
|
||||
#endif//CRPC_SRC_MESSAGE_H_
|
170
src/plugins/c/c_message_plugin.cpp
Normal file
170
src/plugins/c/c_message_plugin.cpp
Normal file
@ -0,0 +1,170 @@
|
||||
//
|
||||
// Created by tqcq on 2023/12/1.
|
||||
//
|
||||
|
||||
#include "c_message_plugin.h"
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
namespace tqcq {
|
||||
|
||||
static std::string GenerateGuardMacro(std::string id, std::string prefix)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << prefix << "_" << id << "_H_";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
static std::string GenerateHeaderFileName(std::string id)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << id << ".h";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string GenerateSourceFileName(std::string id)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << id << ".c";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
CMessagePlugin::CMessagePlugin(std::string generate_path, std::string generate_prefix)
|
||||
: MessagePlugin(std::move(generate_path), std::move(generate_prefix))
|
||||
{}
|
||||
|
||||
void
|
||||
CMessagePlugin::GenerateHeader(std::map<std::string, tqcq::Message::Ptr> message_map)
|
||||
{
|
||||
for (auto &message : message_map) {
|
||||
if (!message.second) {
|
||||
std::cout << "message " << message.first << " is null" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << GenerateIncludeGuardStart(message.second);
|
||||
ss << GenerateIncludeFile(message.second);
|
||||
ss << GenerateStructStart(message.second);
|
||||
ss << GenerateStructItem(message.second);
|
||||
ss << GenerateStructEnd(message.second);
|
||||
ss << GenerateFunctionDeclaration(message.second);
|
||||
ss << GenerateIncludeGuardEnd(message.second);
|
||||
std::ofstream ofs(generate_path() + "/" + GenerateHeaderFileName(message.second->id()));
|
||||
ofs << ss.str();
|
||||
std::cout << ss.str() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CMessagePlugin::GenerateSource(std::map<std::string, tqcq::Message::Ptr> message_map)
|
||||
{
|
||||
for (auto &message : message_map) {
|
||||
std::stringstream ss;
|
||||
ss << GenerateSourceIncludeFile(message.second);
|
||||
ss << GenerateFunctionDefinition(message.second);
|
||||
std::ofstream ofs(generate_path() + "/" + GenerateSourceFileName(message.second->id()));
|
||||
ofs << ss.str();
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
CMessagePlugin::GenerateIncludeGuardStart(Message::Ptr message)
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::string guard_macro = GenerateGuardMacro(message->id(), generate_prefix());
|
||||
ss << "#ifndef " << guard_macro << std::endl;
|
||||
ss << "#define " << guard_macro << std::endl;
|
||||
ss << std::endl;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
CMessagePlugin::GenerateIncludeGuardEnd(Message::Ptr message)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "#endif //" << GenerateGuardMacro(message->id(), generate_prefix()) << std::endl;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
CMessagePlugin::GenerateIncludeFile(Message::Ptr message)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "#include <stdint.h>" << std::endl;
|
||||
ss << std::endl;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
CMessagePlugin::GenerateStructStart(Message::Ptr message)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "typedef struct " << " {" << std::endl;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
CMessagePlugin::GenerateStructItem(Message::Ptr message)
|
||||
{
|
||||
std::stringstream ss;
|
||||
for (auto &item : message->items()) {
|
||||
auto type_name = TranslateTypeToCType(item->type());
|
||||
ss << " " << type_name << " " << item->id() << ";" << std::endl;
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
CMessagePlugin::GenerateStructEnd(Message::Ptr message)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "} " << message->id() << ";" << std::endl;
|
||||
ss << std::endl;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
CMessagePlugin::GenerateFunctionDeclaration(Message::Ptr message)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string
|
||||
CMessagePlugin::GenerateFunctionDefinition(Message::Ptr message)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string
|
||||
CMessagePlugin::GenerateSourceIncludeFile(Message::Ptr message)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "#include \"" << GenerateHeaderFileName(message->id()) << "\"" << std::endl;
|
||||
ss << std::endl;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
CMessagePlugin::TranslateTypeToCType(Item::Type type)
|
||||
{
|
||||
switch(type) {
|
||||
case Item::Type::kInt32:
|
||||
return "int32_t";
|
||||
case Item::Type::kString:
|
||||
return "char*";
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
CMessagePlugin::TranslateTypeToRealType(Item::Type type)
|
||||
{
|
||||
switch(type) {
|
||||
case Item::Type::kInt32:
|
||||
return "int32_t";
|
||||
case Item::Type::kString:
|
||||
return "char*";
|
||||
}
|
||||
}
|
||||
}// namespace tqcq
|
39
src/plugins/c/c_message_plugin.h
Normal file
39
src/plugins/c/c_message_plugin.h
Normal file
@ -0,0 +1,39 @@
|
||||
//
|
||||
// Created by tqcq on 2023/12/1.
|
||||
//
|
||||
|
||||
#ifndef CRPC_SRC_PLUGINS_C_C_MESSAGE_PLUGIN_H_
|
||||
#define CRPC_SRC_PLUGINS_C_C_MESSAGE_PLUGIN_H_
|
||||
|
||||
#include "plugins/message_plugin.h"
|
||||
|
||||
namespace tqcq {
|
||||
|
||||
class CMessagePlugin : public MessagePlugin {
|
||||
public:
|
||||
CMessagePlugin(std::string generate_path, std::string generate_prefix="CRPC");
|
||||
~CMessagePlugin() override = default;
|
||||
void GenerateHeader(std::map<std::string, Message::Ptr> message_map) override;
|
||||
void GenerateSource(std::map<std::string, Message::Ptr> message_map) override;
|
||||
|
||||
private:
|
||||
std::string GenerateIncludeGuardStart(Message::Ptr message);
|
||||
std::string GenerateIncludeGuardEnd(Message::Ptr message);
|
||||
std::string GenerateIncludeFile(Message::Ptr message);
|
||||
|
||||
std::string GenerateStructStart(Message::Ptr message);
|
||||
std::string GenerateStructItem(Message::Ptr message);
|
||||
std::string GenerateStructEnd(Message::Ptr message);
|
||||
|
||||
std::string GenerateFunctionDeclaration(Message::Ptr message);
|
||||
std::string GenerateFunctionDefinition(Message::Ptr message);
|
||||
|
||||
std::string GenerateSourceIncludeFile(Message::Ptr message);
|
||||
|
||||
std::string TranslateTypeToCType(Item::Type type);
|
||||
std::string TranslateTypeToRealType(Item::Type type);
|
||||
};
|
||||
|
||||
}// namespace tqcq
|
||||
|
||||
#endif//CRPC_SRC_PLUGINS_C_C_MESSAGE_PLUGIN_H_
|
30
src/plugins/message_plugin.cpp
Normal file
30
src/plugins/message_plugin.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
//
|
||||
// Created by tqcq on 2023/12/1.
|
||||
//
|
||||
|
||||
#include "message_plugin.h"
|
||||
|
||||
namespace tqcq {
|
||||
MessagePlugin::MessagePlugin(std::string generate_path, std::string generate_prefix)
|
||||
: generate_path_(std::move(generate_path)), generate_prefix_(std::move(generate_prefix))
|
||||
{}
|
||||
|
||||
void
|
||||
MessagePlugin::Generate(std::map<std::string, Message::Ptr> message_map)
|
||||
{
|
||||
GenerateHeader(message_map);
|
||||
GenerateSource(message_map);
|
||||
}
|
||||
|
||||
std::string
|
||||
MessagePlugin::generate_path() const
|
||||
{
|
||||
return generate_path_;
|
||||
}
|
||||
|
||||
std::string
|
||||
MessagePlugin::generate_prefix() const
|
||||
{
|
||||
return generate_prefix_;
|
||||
}
|
||||
}// namespace tqcq
|
31
src/plugins/message_plugin.h
Normal file
31
src/plugins/message_plugin.h
Normal file
@ -0,0 +1,31 @@
|
||||
//
|
||||
// Created by tqcq on 2023/12/1.
|
||||
//
|
||||
|
||||
#ifndef CRPC_SRC_PLUGINS_MESSAGE_PLUGIN_H_
|
||||
#define CRPC_SRC_PLUGINS_MESSAGE_PLUGIN_H_
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "message.h"
|
||||
|
||||
namespace tqcq {
|
||||
|
||||
class MessagePlugin {
|
||||
public:
|
||||
MessagePlugin(std::string generate_path, std::string generate_prefix="CRPC");
|
||||
virtual ~MessagePlugin() = default;
|
||||
virtual void Generate(std::map<std::string, Message::Ptr> message_map);
|
||||
std::string generate_path() const;
|
||||
std::string generate_prefix() const;
|
||||
protected:
|
||||
virtual void GenerateHeader(std::map<std::string, Message::Ptr> message_map) {};
|
||||
virtual void GenerateSource(std::map<std::string, Message::Ptr> message_map) {};
|
||||
private:
|
||||
std::string generate_path_;
|
||||
std::string generate_prefix_;
|
||||
};
|
||||
|
||||
}// namespace tqcq
|
||||
|
||||
#endif//CRPC_SRC_PLUGINS_MESSAGE_PLUGIN_H_
|
45
src/rpc.cpp
Normal file
45
src/rpc.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
//
|
||||
// Created by tqcq on 2023/12/1.
|
||||
//
|
||||
|
||||
#include "rpc.h"
|
||||
#include <sstream>
|
||||
|
||||
namespace tqcq {
|
||||
|
||||
RPC::RPC(std::string id,std::string request_id, std::string response_id)
|
||||
: id_(std::move(id)),
|
||||
request_id_(std::move(request_id)),
|
||||
response_id_(std::move(response_id))
|
||||
{}
|
||||
|
||||
std::string
|
||||
RPC::id() const
|
||||
{
|
||||
return id_;
|
||||
}
|
||||
|
||||
std::string
|
||||
RPC::request_id() const
|
||||
{
|
||||
return request_id_;
|
||||
}
|
||||
|
||||
std::string
|
||||
RPC::response_id() const
|
||||
{
|
||||
return response_id_;
|
||||
}
|
||||
|
||||
std::string
|
||||
RPC::ToString()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "rpc " << id_ << " (";
|
||||
ss << request_id_;
|
||||
ss << ") return (";
|
||||
ss << response_id_;
|
||||
ss << ");";
|
||||
return ss.str();
|
||||
}
|
||||
}// namespace tqcq
|
31
src/rpc.h
Normal file
31
src/rpc.h
Normal file
@ -0,0 +1,31 @@
|
||||
//
|
||||
// Created by tqcq on 2023/12/1.
|
||||
//
|
||||
|
||||
#ifndef CRPC_SRC_RPC_H_
|
||||
#define CRPC_SRC_RPC_H_
|
||||
|
||||
#include "message.h"
|
||||
|
||||
namespace tqcq {
|
||||
|
||||
// rpc: RPC_TYPE ID '(' messageStatement ')' 'return' '(' messageStatement ')' ';';
|
||||
class RPC {
|
||||
public:
|
||||
using Ptr = std::shared_ptr<RPC>;
|
||||
|
||||
RPC(std::string id, std::string request_id, std::string response_id);
|
||||
std::string id() const;
|
||||
std::string request_id() const;
|
||||
std::string response_id() const;
|
||||
|
||||
std::string ToString();
|
||||
private:
|
||||
std::string id_;
|
||||
std::string request_id_;
|
||||
std::string response_id_;
|
||||
};
|
||||
|
||||
}// namespace tqcq
|
||||
|
||||
#endif//CRPC_SRC_RPC_H_
|
50
src/service.cpp
Normal file
50
src/service.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
//
|
||||
// Created by tqcq on 2023/12/1.
|
||||
//
|
||||
|
||||
#include "service.h"
|
||||
#include <sstream>
|
||||
|
||||
namespace tqcq {
|
||||
Service::Service(std::string id) : id_(std::move(id)) {}
|
||||
|
||||
std::string
|
||||
Service::id() const
|
||||
{
|
||||
return id_;
|
||||
}
|
||||
|
||||
void
|
||||
Service::AddRPC(RPC::Ptr rpc)
|
||||
{
|
||||
rpcs_.push_back(std::move(rpc));
|
||||
}
|
||||
|
||||
void
|
||||
Service::SetRPCs(std::vector<RPC::Ptr> rpcs)
|
||||
{
|
||||
rpcs_ = std::move(rpcs);
|
||||
}
|
||||
|
||||
std::vector<RPC::Ptr>
|
||||
Service::rpcs() const
|
||||
{
|
||||
return rpcs_;
|
||||
}
|
||||
|
||||
std::string
|
||||
Service::ToString()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "service " << id_ << " {";
|
||||
for (auto& rpc : rpcs_) {
|
||||
ss << std::endl;
|
||||
ss << " " << rpc->ToString();
|
||||
}
|
||||
if (!rpcs_.empty()) {
|
||||
ss << std::endl;
|
||||
}
|
||||
ss << "};";
|
||||
return ss.str();
|
||||
}
|
||||
}// namespace tqcq
|
31
src/service.h
Normal file
31
src/service.h
Normal file
@ -0,0 +1,31 @@
|
||||
//
|
||||
// Created by tqcq on 2023/12/1.
|
||||
//
|
||||
|
||||
#ifndef CRPC_SRC_SERVICE_H_
|
||||
#define CRPC_SRC_SERVICE_H_
|
||||
|
||||
#include "rpc.h"
|
||||
|
||||
namespace tqcq {
|
||||
|
||||
// serviceStatement: SERVICE_TYPE ID '{' rpc* '}' ';';
|
||||
class Service {
|
||||
public:
|
||||
using Ptr = std::shared_ptr<Service>;
|
||||
|
||||
Service(std::string id);
|
||||
std::string id() const;
|
||||
void AddRPC(RPC::Ptr rpc);
|
||||
void SetRPCs(std::vector<RPC::Ptr> rpcs);
|
||||
std::vector<RPC::Ptr> rpcs() const;
|
||||
|
||||
std::string ToString();
|
||||
private:
|
||||
std::string id_;
|
||||
std::vector<RPC::Ptr> rpcs_;
|
||||
};
|
||||
|
||||
}// namespace tqcq
|
||||
|
||||
#endif//CRPC_SRC_SERVICE_H_
|
16
src/test.proto
Normal file
16
src/test.proto
Normal file
@ -0,0 +1,16 @@
|
||||
syntax = "proto3";
|
||||
|
||||
message TestMessage {
|
||||
int32 id = 1;
|
||||
string name = 2;
|
||||
};
|
||||
|
||||
service TestService {
|
||||
rpc TestMethod(TestMessage) returns (TestMessage);
|
||||
};
|
||||
|
||||
message SearchRequest {
|
||||
string query = 1;
|
||||
int32 page_number = 2;
|
||||
int32 results_per_page = 3;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user