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…
Reference in New Issue
Block a user