aboutsummaryrefslogtreecommitdiffstats
path: root/protoc-gen-csi/protoc_gen_csi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protoc-gen-csi/protoc_gen_csi.cpp')
-rw-r--r--protoc-gen-csi/protoc_gen_csi.cpp114
1 files changed, 114 insertions, 0 deletions
diff --git a/protoc-gen-csi/protoc_gen_csi.cpp b/protoc-gen-csi/protoc_gen_csi.cpp
new file mode 100644
index 00000000000..fa9c3e089ca
--- /dev/null
+++ b/protoc-gen-csi/protoc_gen_csi.cpp
@@ -0,0 +1,114 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include <google/protobuf/compiler/plugin.h>
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/descriptor.h>
+
+using namespace google::protobuf;
+using namespace google::protobuf::compiler;
+
+class MyGen : public CodeGenerator {
+public:
+ bool Generate(const FileDescriptor * file, const std::string & parameter,
+ GeneratorContext * generator_context, std::string * error) const override;
+ ~MyGen();
+};
+
+MyGen::~MyGen() = default;
+
+int main(int argc, char* argv[]) {
+ MyGen generator;
+ return PluginMain(argc, argv, &generator);
+}
+
+void write_line(io::ZeroCopyOutputStream *target, const std::string &line) {
+ void *data = nullptr;
+ const char *src = line.c_str();
+ int left = line.size() + 1;
+ while (left > 0) {
+ int size = left;
+ if (target->Next(&data, &size)) {
+ if (size == 0) continue;
+ if (size >= left) {
+ memcpy(data, src, left);
+ char * buf = static_cast<char *>(data);
+ buf[left - 1] = '\n';
+ if (size > left) {
+ target->BackUp(size - left);
+ }
+ return;
+ } else {
+ memcpy(data, src, size);
+ left -= size;
+ src += size;
+ }
+ } else {
+ perror("target->Next() returned false");
+ std::string message = "Error writing output: ";
+ message += strerror(errno);
+ throw message;
+ }
+ }
+}
+
+void my_generate(const std::string &name,
+ const FileDescriptor &file,
+ GeneratorContext &context)
+{
+ if (file.dependency_count() > 0
+ || file.public_dependency_count() > 0
+ || file.weak_dependency_count() > 0)
+ {
+ std::string message = "Importing dependencies not supported";
+ throw message;
+ }
+ if (file.extension_count() > 0) {
+ std::string message = "Extensions not supported";
+ throw message;
+ }
+ if (file.is_placeholder()) {
+ std::string message = "Unexpected placeholder file";
+ throw message;
+ }
+ auto filename_csi_h = name + ".csi.h";
+ auto csi_h = context.Open(filename_csi_h);
+ write_line(csi_h, "// DO NOT EDIT (generated by protoc-gen-csi)");
+ write_line(csi_h, "// Coroutine Service Interface: " + name);
+ write_line(csi_h, "#pragma once");
+
+ auto filename_csi_cpp = name + ".csi.cpp";
+ auto csi_cpp = context.Open(filename_csi_cpp);
+ write_line(csi_cpp, "// DO NOT EDIT (generated by protoc-gen-csi)");
+ write_line(csi_cpp, "// Coroutine Service Interface: " + name);
+ write_line(csi_cpp, "#include \"" + filename_csi_h + "\"");
+}
+
+bool MyGen::Generate(const FileDescriptor * file, const std::string & parameter,
+ GeneratorContext * generator_context, std::string * error) const
+{
+ std::string name = "[unknown]";
+ try {
+ if (file == nullptr) {
+ std::string m = "No FileDescriptor";
+ throw m;
+ }
+ name = file->name();
+ if (name.ends_with(".proto")) {
+ name = name.substr(0, name.size() - 6);
+ }
+ if (generator_context == nullptr) {
+ std::string m = "No GeneratorContext";
+ throw m;
+ }
+ if (! parameter.empty()) {
+ std::string m = "unknown command line parameter " + parameter;
+ throw m;
+ }
+ my_generate(name, *file, *generator_context);
+ } catch (const std::string &message) {
+ *error = name + ": " + message;
+ return false;
+ }
+ return true;
+}