Add comments to the generated header file
diff --git a/src/compiler/config.h b/src/compiler/config.h
index fea976c..a826dd9 100644
--- a/src/compiler/config.h
+++ b/src/compiler/config.h
@@ -44,6 +44,7 @@
#define GRPC_CUSTOM_FILEDESCRIPTOR ::google::protobuf::FileDescriptor
#define GRPC_CUSTOM_METHODDESCRIPTOR ::google::protobuf::MethodDescriptor
#define GRPC_CUSTOM_SERVICEDESCRIPTOR ::google::protobuf::ServiceDescriptor
+#define GRPC_CUSTOM_SOURCELOCATION ::google::protobuf::SourceLocation
#endif
#ifndef GRPC_CUSTOM_CODEGENERATOR
@@ -74,6 +75,7 @@
typedef GRPC_CUSTOM_FILEDESCRIPTOR FileDescriptor;
typedef GRPC_CUSTOM_METHODDESCRIPTOR MethodDescriptor;
typedef GRPC_CUSTOM_SERVICEDESCRIPTOR ServiceDescriptor;
+typedef GRPC_CUSTOM_SOURCELOCATION SourceLocation;
namespace compiler {
typedef GRPC_CUSTOM_CODEGENERATOR CodeGenerator;
typedef GRPC_CUSTOM_GENERATORCONTEXT GeneratorContext;
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index b133699..97455cd 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -101,6 +101,7 @@
printer->Print(vars,
"// If you make any local change, they will be lost.\n");
printer->Print(vars, "// source: $filename$\n");
+ printer->Print(file->GetLeadingComments().c_str());
printer->Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
printer->Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
printer->Print(vars, "\n");
@@ -455,6 +456,7 @@
(*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name();
(*vars)["Response"] = method->output_type_name();
+ printer->Print(method->GetLeadingComments().c_str());
if (method->NoStreaming()) {
printer->Print(*vars,
"virtual ::grpc::Status $Method$("
@@ -479,6 +481,7 @@
"::grpc::ServerReaderWriter< $Response$, $Request$>* stream);"
"\n");
}
+ printer->Print(method->GetTrailingComments().c_str());
}
void PrintHeaderServerMethodAsync(
@@ -673,6 +676,7 @@
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Service"] = service->name();
+ printer->Print(service->GetLeadingComments().c_str());
printer->Print(*vars,
"class $Service$ GRPC_FINAL {\n"
" public:\n");
@@ -685,7 +689,9 @@
printer->Indent();
printer->Print("virtual ~StubInterface() {}\n");
for (int i = 0; i < service->method_count(); ++i) {
+ printer->Print(service->method(i)->GetLeadingComments().c_str());
PrintHeaderClientMethodInterfaces(printer, service->method(i).get(), vars, true);
+ printer->Print(service->method(i)->GetTrailingComments().c_str());
}
printer->Outdent();
printer->Print("private:\n");
@@ -761,6 +767,7 @@
printer->Outdent();
printer->Print("};\n");
+ printer->Print(service->GetTrailingComments().c_str());
}
grpc::string GetHeaderServices(File *file,
@@ -817,6 +824,8 @@
printer->Print(vars, "\n");
printer->Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n");
+
+ printer->Print(file->GetTrailingComments().c_str());
}
return output;
}
@@ -836,6 +845,7 @@
printer->Print(vars,
"// If you make any local change, they will be lost.\n");
printer->Print(vars, "// source: $filename$\n\n");
+
printer->Print(vars, "#include \"$filename_base$.pb.h\"\n");
printer->Print(vars, "#include \"$filename_base$.grpc.pb.h\"\n");
printer->Print(vars, "\n");
diff --git a/src/compiler/cpp_generator.h b/src/compiler/cpp_generator.h
index 99a60a2..1e68dfe 100644
--- a/src/compiler/cpp_generator.h
+++ b/src/compiler/cpp_generator.h
@@ -64,8 +64,15 @@
grpc::string grpc_search_path;
};
+// A common interface for objects having comments in the source.
+struct CommentHolder {
+ virtual ~CommentHolder() {}
+ virtual grpc::string GetLeadingComments() const = 0;
+ virtual grpc::string GetTrailingComments() const = 0;
+};
+
// An abstract interface representing a method.
-struct Method {
+struct Method : public CommentHolder {
virtual ~Method() {}
virtual grpc::string name() const = 0;
@@ -80,7 +87,7 @@
};
// An abstract interface representing a service.
-struct Service {
+struct Service : public CommentHolder {
virtual ~Service() {}
virtual grpc::string name() const = 0;
@@ -101,7 +108,7 @@
// An interface that allows the source generated to be output using various
// libraries/idls/serializers.
-struct File {
+struct File : public CommentHolder {
virtual ~File() {}
virtual grpc::string filename() const = 0;
diff --git a/src/compiler/cpp_plugin.cc b/src/compiler/cpp_plugin.cc
index f703c64..6128b81 100644
--- a/src/compiler/cpp_plugin.cc
+++ b/src/compiler/cpp_plugin.cc
@@ -35,11 +35,46 @@
//
#include <memory>
+#include <sstream>
#include "src/compiler/config.h"
#include "src/compiler/cpp_generator.h"
#include "src/compiler/cpp_generator_helpers.h"
+#include "src/compiler/generator_helpers.h"
+
+grpc::string GenerateComments(const std::vector<grpc::string> &in) {
+ std::ostringstream oss;
+ for (const grpc::string &elem : in) {
+ if (elem.empty()) {
+ oss << "//\n";
+ } else if (elem[0] == ' ') {
+ oss << "//" << elem << "\n";
+ } else {
+ oss << "// " << elem << "\n";
+ }
+ }
+ return oss.str();
+}
+
+// Get leading or trailing comments in a string. Comment lines start with "// ".
+// Leading detached comments are put in in front of leading comments.
+template <typename DescriptorType>
+grpc::string GetComments(const DescriptorType *desc, bool leading) {
+ std::vector<grpc::string> out;
+ if (leading) {
+ grpc_generator::GetComment(
+ desc, grpc_generator::COMMENTTYPE_LEADING_DETACHED, &out);
+ std::vector<grpc::string> leading;
+ grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_LEADING,
+ &leading);
+ out.insert(out.end(), leading.begin(), leading.end());
+ } else {
+ grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_TRAILING,
+ &out);
+ }
+ return GenerateComments(out);
+}
class ProtoBufMethod : public grpc_cpp_generator::Method {
public:
@@ -71,6 +106,12 @@
return method_->client_streaming() && method_->server_streaming();
}
+ grpc::string GetLeadingComments() const { return GetComments(method_, true); }
+
+ grpc::string GetTrailingComments() const {
+ return GetComments(method_, false);
+ }
+
private:
const grpc::protobuf::MethodDescriptor *method_;
};
@@ -88,6 +129,14 @@
new ProtoBufMethod(service_->method(i)));
};
+ grpc::string GetLeadingComments() const {
+ return GetComments(service_, true);
+ }
+
+ grpc::string GetTrailingComments() const {
+ return GetComments(service_, false);
+ }
+
private:
const grpc::protobuf::ServiceDescriptor *service_;
};
@@ -136,6 +185,10 @@
new ProtoBufPrinter(str));
}
+ grpc::string GetLeadingComments() const { return GetComments(file_, true); }
+
+ grpc::string GetTrailingComments() const { return GetComments(file_, false); }
+
private:
const grpc::protobuf::FileDescriptor *file_;
};
diff --git a/src/compiler/generator_helpers.h b/src/compiler/generator_helpers.h
index e1bb66a..7cfea9d 100644
--- a/src/compiler/generator_helpers.h
+++ b/src/compiler/generator_helpers.h
@@ -35,6 +35,9 @@
#define GRPC_INTERNAL_COMPILER_GENERATOR_HELPERS_H
#include <map>
+#include <sstream>
+#include <string>
+#include <vector>
#include "src/compiler/config.h"
@@ -165,6 +168,44 @@
}
}
+inline void Split(const grpc::string &s, char delim,
+ std::vector<grpc::string> *append_to) {
+ std::istringstream iss(s);
+ grpc::string piece;
+ while (std::getline(iss, piece)) {
+ append_to->push_back(piece);
+ }
+}
+
+enum CommentType {
+ COMMENTTYPE_LEADING,
+ COMMENTTYPE_TRAILING,
+ COMMENTTYPE_LEADING_DETACHED
+};
+
+// Get all the comments and append each line to out.
+template <typename DescriptorType>
+inline void GetComment(const DescriptorType *desc, CommentType type,
+ std::vector<grpc::string> *out) {
+ grpc::protobuf::SourceLocation location;
+ if (!desc->GetSourceLocation(&location)) {
+ return;
+ }
+ if (type == COMMENTTYPE_LEADING || type == COMMENTTYPE_TRAILING) {
+ const grpc::string &comments = type == COMMENTTYPE_LEADING
+ ? location.leading_comments
+ : location.trailing_comments;
+ Split(comments, '\n', out);
+ } else if (type == COMMENTTYPE_LEADING_DETACHED) {
+ for (int i = 0; i < location.leading_detached_comments.size(); i++) {
+ Split(location.leading_detached_comments[i], '\n', out);
+ out->push_back("");
+ }
+ } else {
+ abort();
+ }
+}
+
} // namespace grpc_generator
#endif // GRPC_INTERNAL_COMPILER_GENERATOR_HELPERS_H