feat add code generator
Some checks failed
linux-x64-gcc / linux-gcc (Debug) (push) Failing after 1m25s
linux-arm-gcc / linux-gcc-armhf (push) Successful in 2m5s
linux-mips64-gcc / linux-gcc-mips64el (Debug) (push) Successful in 2m5s
linux-x64-gcc / linux-gcc (Release) (push) Successful in 2m30s
linux-aarch64-cpu-gcc / linux-gcc-aarch64 (push) Successful in 2m42s
linux-mips64-gcc / linux-gcc-mips64el (Release) (push) Successful in 4m42s

This commit is contained in:
tqcq 2024-04-13 10:14:57 +08:00
parent fdbce08c6c
commit ebea797d67
11 changed files with 202 additions and 3 deletions

View File

@ -59,7 +59,7 @@ endif()
option(protobuf_BUILD_TESTS "Build tests" OFF)
option(protobuf_BUILD_CONFORMANCE "Build conformance tests" OFF)
option(protobuf_BUILD_EXAMPLES "Build examples" OFF)
option(protobuf_BUILD_PROTOC_BINARIES "Build libprotoc and protoc compiler" OFF)
option(protobuf_BUILD_PROTOC_BINARIES "Build libprotoc and protoc compiler" ON)
option(protobuf_BUILD_LIBPROTOC "Build libprotoc" OFF)
option(protobuf_DISABLE_RTTI "Remove runtime type information in the binaries"
OFF)

View File

@ -16,6 +16,7 @@ option(SLED_BUILD_BENCHMARK "Build benchmark" OFF)
option(SLED_BUILD_TESTS "Build tests" OFF)
option(SLED_BUILD_FUZZ "Build fuzzer test" OFF)
option(SLED_LOCATION_PATH "" "sled/src/sled/system/location.cc")
option(SLED_BUILD_PROTOC_PLUGIN "Build protoc plugin" OFF)
set(BUILD_STATIC ON)
set(BUILD_RTTR_DYNAMIC OFF)
@ -97,6 +98,7 @@ target_sources(
target_link_libraries(
sled
PUBLIC rpc_core fmt marl Async++ minilua protobuf::libprotobuf
# protobuf::libprotoc
PRIVATE dl
# protobuf::libprotobuf ${WHOLE_ARCHIVE_WRAPPER_START}
# tcmalloc_and_profiler_static ${WHOLE_ARCHIVE_WRAPPER_END}
@ -105,6 +107,10 @@ target_link_libraries(
# set fPIC
set_target_properties(sled PROPERTIES POSITION_INDEPENDENT_CODE ON)
if(SLED_BUILD_PROTOC_PLUGIN)
add_subdirectory(src/protoc_gen_sled)
endif()
if(SLED_BUILD_BENCHMARK)
# if(NOT TARGET benchmark) find_package(mbenchmark REQUIRED) endif()

View File

@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.10)
project(protoc-gen-sled LANGUAGES C CXX)
add_executable(${PROJECT_NAME} main.cc sled_generator.cc)
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(${PROJECT_NAME} PRIVATE libprotoc sled)
install(TARGETS ${PROJECT_NAME} DESTINATION bin)

View File

@ -0,0 +1,17 @@
#include "sled_generator.h"
#include <google/protobuf/compiler/command_line_interface.h>
#include <google/protobuf/compiler/cpp/cpp_generator.h>
#include <google/protobuf/compiler/plugin.h>
int
main(int argc, char *argv[])
{
google::protobuf::compiler::CommandLineInterface cli;
// google::protobuf::compiler::cpp::CppGenerator cpp_generator;
// cli.RegisterGenerator("--cpp_out", &cpp_generator, "Generate C++ source code.");
sled::SledGenerator sled_generator;
cli.RegisterGenerator("--sled_out", &sled_generator, "sled cpp rpc generator");
return google::protobuf::compiler::PluginMain(argc, argv, &sled_generator);
}

View File

@ -0,0 +1,54 @@
#include "sled_generator.h"
#include <google/protobuf/compiler/plugin.pb.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/io/printer.h>
#include <sled/sled.h>
using namespace google::protobuf;
using namespace google::protobuf::compiler;
using namespace google::protobuf::io;
namespace sled {
void
PrintMessage(Printer &printer, const Descriptor *msg)
{
printer.Print("- $name$\n", "name", msg->name());
printer.Indent();
for (int i = 0; i < msg->nested_type_count(); ++i) { PrintMessage(printer, msg->nested_type(i)); }
printer.Outdent();
}
void
PrintService(Printer &printer, const ServiceDescriptor *service)
{
inja::json data;
data["classname"] = service->name();
data["full_name"] = service->full_name();
printer.Print("- $name$\n", "name", service->full_name());
printer.Indent();
for (int i = 0; i < service->method_count(); i++) {
const MethodDescriptor *method = service->method(i);
printer.Print("- $name$\n", "name", method->name());
printer.Indent();
printer.Print("request: $name$ $file$\n", "name", method->input_type()->name(), "file", method->file()->name());
printer
.Print("response: $name$ $file$\n", "name", method->output_type()->name(), "file", method->file()->name());
printer.Outdent();
}
printer.Outdent();
}
bool
SledGenerator::Generate(const FileDescriptor *file,
const std::string &parameter,
GeneratorContext *generator_context,
std::string *error) const
{
auto *out_stream = generator_context->Open(file->name() + ".txt");
Printer printer(out_stream, '$');
for (int i = 0; i < file->message_type_count(); i++) { PrintMessage(printer, file->message_type(i)); }
for (int i = 0; i < file->service_count(); i++) { PrintService(printer, file->service(i)); }
return true;
}
}// namespace sled

View File

@ -0,0 +1,22 @@
#ifndef SLED_SLED_GENERATOR_SLED_GENERATOR_H
#define SLED_SLED_GENERATOR_SLED_GENERATOR_H
#pragma once
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/descriptor.h>
using namespace google::protobuf;
using namespace google::protobuf::compiler;
namespace sled {
class SledGenerator : public google::protobuf::compiler::CodeGenerator {
public:
~SledGenerator() override = default;
bool Generate(const FileDescriptor *file,
const std::string &parameter,
GeneratorContext *generator_context,
std::string *error) const override;
};
}// namespace sled
#endif// SLED_SLED_GENERATOR_SLED_GENERATOR_H

View File

@ -1,7 +1,7 @@
#include "sled/system/pid.h"
namespace sled {
pid_t
ProcessId
GetCachedPID()
{
static pid_t cached_pid = getpid();

View File

@ -11,6 +11,12 @@ typedef unsigned long pid_t;
#endif
namespace sled {
pid_t GetCachedPID();
#ifdef _WIN32
typedef unsigned long ProcessId;
#else
typedef pid_t ProcessId;
#endif
ProcessId GetCachedPID();
}// namespace sled
#endif// SLED_SYSTEM_PID_H

View File

@ -0,0 +1,8 @@
#include "sled/system/process.h"
namespace sled {
Process::Process(const Option &option) : option(option) {}
Process::~Process() noexcept { CloseAllFileDescriptors(); }
}// namespace sled

79
src/sled/system/process.h Normal file
View File

@ -0,0 +1,79 @@
#ifndef SLED_SLED_SYSTEM_PROCESS_H
#define SLED_SLED_SYSTEM_PROCESS_H
#pragma once
#include "sled/optional.h"
#include "sled/synchronization/mutex.h"
#include "sled/system/pid.h"
#include <functional>
#include <map>
#include <string>
#include <vector>
namespace sled {
class Process {
public:
using ByteReader = std::function<void(const char *, std::size_t)>;
struct Option {
std::vector<std::string> cmd_args;
std::string working_dir;
std::map<std::string, std::string> envs;
ByteReader stdout_reader = nullptr;
ByteReader stderr_reader = nullptr;
bool open_stdin = false;
std::size_t stout_buffer_size = 128 * 1024;
std::size_t stderr_buffer_size = 128 * 1024;
bool inherit_file_descriptors = false;
};
struct Builder {
Builder &SetCmdArgs(const std::vector<std::string> &args);
Builder &AppendCmdArg(const std::string &arg);
Builder &SetEnvs(const std::map<std::string, std::string> &env);
Builder &AppendEnv(const std::string &key, const std::string &value);
Builder &SetWorkingDir(const std::string &dir);
Builder &SetStdoutReader(ByteReader reader);
Builder &SetStderrReader(ByteReader reader);
Builder &SetOpenStdin(bool open);
Builder &SetStdoutBufferSize(std::size_t size);
Builder &SetStderrBufferSize(std::size_t size);
Builder &SetInheritFileDescriptors(bool inherit);
Process Build();
private:
Option option;
};
public:
Process(const Option &option);
~Process() noexcept;
ProcessId id() const noexcept { return id_; }
sled::optional<int> exit_status() noexcept;
void CloseStdin() noexcept;
void Kill(bool force = false) noexcept;
void Signal(int signal) noexcept;
std::size_t Write(const char *data, std::size_t size);
std::size_t Write(const std::string &data);
public:
static void Kill(ProcessId id, bool force = false) noexcept;
static void Signal(ProcessId id, int signal) noexcept;
private:
void CloseAllFileDescriptors() noexcept;
const Option option;
ProcessId id_;
std::unique_ptr<int> stdout_fd_;
std::unique_ptr<int> stderr_fd_;
std::unique_ptr<int> stdin_fd_;
Option option_;
};
}// namespace sled
#endif// SLED_SLED_SYSTEM_PROCESS_H

View File