From 9efec8eaad91fa4f5b056f910264b7a5ee9c20fe Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 14 Apr 2016 14:34:55 -0700 Subject: Add comments to the generated header file --- src/compiler/config.h | 2 ++ src/compiler/cpp_generator.cc | 10 ++++++++ src/compiler/cpp_generator.h | 13 +++++++--- src/compiler/cpp_plugin.cc | 53 ++++++++++++++++++++++++++++++++++++++++ src/compiler/generator_helpers.h | 41 +++++++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/compiler/config.h b/src/compiler/config.h index fea976c318..a826dd9744 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_DESCRIPTOR Descriptor; 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 b133699306..97455cdbfd 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -101,6 +101,7 @@ grpc::string GetHeaderPrologue(File *file, const Parameters ¶ms) { 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 @@ void PrintHeaderServerMethodSync(Printer *printer, const Method *method, (*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 @@ void PrintHeaderServerMethodSync(Printer *printer, const Method *method, "::grpc::ServerReaderWriter< $Response$, $Request$>* stream);" "\n"); } + printer->Print(method->GetTrailingComments().c_str()); } void PrintHeaderServerMethodAsync( @@ -673,6 +676,7 @@ void PrintHeaderService(Printer *printer, std::map *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 @@ void PrintHeaderService(Printer *printer, 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 @@ void PrintHeaderService(Printer *printer, printer->Outdent(); printer->Print("};\n"); + printer->Print(service->GetTrailingComments().c_str()); } grpc::string GetHeaderServices(File *file, @@ -817,6 +824,8 @@ grpc::string GetHeaderEpilogue(File *file, 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 @@ grpc::string GetSourcePrologue(File *file, 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 99a60a2eae..1e68dfe3df 100644 --- a/src/compiler/cpp_generator.h +++ b/src/compiler/cpp_generator.h @@ -64,8 +64,15 @@ struct Parameters { 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 @@ struct Method { }; // An abstract interface representing a service. -struct Service { +struct Service : public CommentHolder { virtual ~Service() {} virtual grpc::string name() const = 0; @@ -101,7 +108,7 @@ struct Printer { // 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 f703c6453d..6128b816a4 100644 --- a/src/compiler/cpp_plugin.cc +++ b/src/compiler/cpp_plugin.cc @@ -35,11 +35,46 @@ // #include +#include #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 &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 +grpc::string GetComments(const DescriptorType *desc, bool leading) { + std::vector out; + if (leading) { + grpc_generator::GetComment( + desc, grpc_generator::COMMENTTYPE_LEADING_DETACHED, &out); + std::vector 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 @@ class ProtoBufMethod : public grpc_cpp_generator::Method { 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 @@ class ProtoBufService : public grpc_cpp_generator::Service { 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 @@ class ProtoBufFile : public grpc_cpp_generator::File { 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 e1bb66a875..7cfea9d96d 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 +#include +#include +#include #include "src/compiler/config.h" @@ -165,6 +168,44 @@ inline MethodType GetMethodType(const grpc::protobuf::MethodDescriptor *method) } } +inline void Split(const grpc::string &s, char delim, + std::vector *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 +inline void GetComment(const DescriptorType *desc, CommentType type, + std::vector *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 -- cgit v1.2.3