aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/cpp_generator.cc153
-rw-r--r--src/compiler/cpp_generator.h19
-rw-r--r--src/compiler/cpp_plugin.cc36
3 files changed, 182 insertions, 26 deletions
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index 0a84c73520..c78f0333d8 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -109,8 +109,47 @@ bool HasBidiStreaming(const grpc::protobuf::FileDescriptor *file) {
}
return false;
}
+
+grpc::string FilenameIdentifier(const grpc::string& filename) {
+ grpc::string result;
+ for (unsigned i = 0; i < filename.size(); i++) {
+ char c = filename[i];
+ if (isalnum(c)) {
+ result.push_back(c);
+ } else {
+ static char hex[] = "0123456789abcdef";
+ result.push_back('_');
+ result.push_back(hex[(c >> 4) & 0xf]);
+ result.push_back(hex[c & 0xf]);
+ }
+ }
+ return result;
+}
} // namespace
+grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params) {
+ grpc::string output;
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ grpc::protobuf::io::Printer printer(&output_stream, '$');
+ std::map<grpc::string, grpc::string> vars;
+
+ vars["filename"] = file->name();
+ vars["filename_identifier"] = FilenameIdentifier(file->name());
+ vars["filename_base"] = grpc_generator::StripProto(file->name());
+
+ printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
+ printer.Print(vars, "// If you make any local change, they will be lost.\n");
+ printer.Print(vars, "// source: $filename$\n");
+ printer.Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
+ printer.Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
+ printer.Print(vars, "\n");
+ printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
+ printer.Print(vars, "\n");
+
+ return output;
+}
+
grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
const Parameters &params) {
grpc::string temp =
@@ -156,17 +195,21 @@ grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
"class ServerAsyncReaderWriter;\n");
}
temp.append("} // namespace grpc\n");
- return temp;
-}
-grpc::string GetSourceIncludes(const Parameters &param) {
- return "#include <grpc++/async_unary_call.h>\n"
- "#include <grpc++/channel_interface.h>\n"
- "#include <grpc++/impl/client_unary_call.h>\n"
- "#include <grpc++/impl/rpc_method.h>\n"
- "#include <grpc++/impl/rpc_service_method.h>\n"
- "#include <grpc++/impl/service_type.h>\n"
- "#include <grpc++/stream.h>\n";
+ temp.append("\n");
+
+ std::vector<grpc::string> parts =
+ grpc_generator::tokenize(file->package(), ".");
+
+ for (auto part = parts.begin(); part != parts.end(); part++) {
+ temp.append("namespace ");
+ temp.append(*part);
+ temp.append(" {\n");
+ }
+
+ temp.append("\n");
+
+ return temp;
}
void PrintHeaderClientMethod(grpc::protobuf::io::Printer *printer,
@@ -378,6 +421,78 @@ grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
return output;
}
+grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params) {
+ grpc::string output;
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ grpc::protobuf::io::Printer printer(&output_stream, '$');
+ std::map<grpc::string, grpc::string> vars;
+
+ vars["filename"] = file->name();
+ vars["filename_identifier"] = FilenameIdentifier(file->name());
+
+ std::vector<grpc::string> parts =
+ grpc_generator::tokenize(file->package(), ".");
+
+ for (auto part = parts.rbegin(); part != parts.rend(); part++) {
+ vars["part"] = *part;
+ printer.Print(vars, "} // namespace $part$\n");
+ }
+
+ printer.Print(vars, "\n\n");
+ printer.Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n");
+
+ return output;
+}
+
+grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params) {
+ grpc::string output;
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ grpc::protobuf::io::Printer printer(&output_stream, '$');
+ std::map<grpc::string, grpc::string> vars;
+
+ vars["filename"] = file->name();
+ vars["filename_base"] = grpc_generator::StripProto(file->name());
+
+ printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
+ 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");
+
+ return output;
+}
+
+grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &param) {
+ grpc::string output;
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ grpc::protobuf::io::Printer printer(&output_stream, '$');
+ std::map<grpc::string, grpc::string> vars;
+
+ printer.Print(vars, "#include <grpc++/async_unary_call.h>\n");
+ printer.Print(vars, "#include <grpc++/channel_interface.h>\n");
+ printer.Print(vars, "#include <grpc++/impl/client_unary_call.h>\n");
+ printer.Print(vars, "#include <grpc++/impl/rpc_method.h>\n");
+ printer.Print(vars, "#include <grpc++/impl/rpc_service_method.h>\n");
+ printer.Print(vars, "#include <grpc++/impl/service_type.h>\n");
+ printer.Print(vars, "#include <grpc++/stream.h>\n");
+
+ std::vector<grpc::string> parts =
+ grpc_generator::tokenize(file->package(), ".");
+
+ for (auto part = parts.begin(); part != parts.end(); part++) {
+ vars["part"] = *part;
+ printer.Print(vars, "namespace $part$ {\n");
+ }
+
+ printer.Print(vars, "\n");
+
+ return output;
+}
+
void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
const grpc::protobuf::MethodDescriptor *method,
std::map<grpc::string, grpc::string> *vars) {
@@ -741,4 +856,22 @@ grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
return output;
}
+grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params) {
+ grpc::string temp;
+
+ std::vector<grpc::string> parts =
+ grpc_generator::tokenize(file->package(), ".");
+
+ for (auto part = parts.begin(); part != parts.end(); part++) {
+ temp.append("} // namespace ");
+ temp.append(*part);
+ temp.append("\n");
+ }
+
+ temp.append("\n");
+
+ return temp;
+}
+
} // namespace grpc_cpp_generator
diff --git a/src/compiler/cpp_generator.h b/src/compiler/cpp_generator.h
index 04ad71c067..70c2e985f6 100644
--- a/src/compiler/cpp_generator.h
+++ b/src/compiler/cpp_generator.h
@@ -44,12 +44,25 @@ struct Parameters {
grpc::string services_namespace;
};
+// Return the prologue of the generated header file.
+grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params);
+
// Return the includes needed for generated header file.
grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
const Parameters &params);
// Return the includes needed for generated source file.
-grpc::string GetSourceIncludes(const Parameters &params);
+grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params);
+
+// Return the epilogue of the generated header file.
+grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params);
+
+// Return the prologue of the generated source file.
+grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params);
// Return the services for generated header file.
grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
@@ -59,6 +72,10 @@ grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
const Parameters &params);
+// Return the epilogue of the generated source file.
+grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params);
+
} // namespace grpc_cpp_generator
#endif // GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
diff --git a/src/compiler/cpp_plugin.cc b/src/compiler/cpp_plugin.cc
index acbe128213..88c704948e 100644
--- a/src/compiler/cpp_plugin.cc
+++ b/src/compiler/cpp_plugin.cc
@@ -58,11 +58,6 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
return false;
}
- if (file->service_count() == 0) {
- // No services. Do nothing.
- return true;
- }
-
grpc_cpp_generator::Parameters generator_parameters;
if (!parameter.empty()) {
@@ -84,16 +79,27 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
grpc::string file_name = grpc_generator::StripProto(file->name());
- // Generate .pb.h
- Insert(context, file_name + ".pb.h", "includes",
- grpc_cpp_generator::GetHeaderIncludes(file, generator_parameters));
- Insert(context, file_name + ".pb.h", "namespace_scope",
- grpc_cpp_generator::GetHeaderServices(file, generator_parameters));
- // Generate .pb.cc
- Insert(context, file_name + ".pb.cc", "includes",
- grpc_cpp_generator::GetSourceIncludes(generator_parameters));
- Insert(context, file_name + ".pb.cc", "namespace_scope",
- grpc_cpp_generator::GetSourceServices(file, generator_parameters));
+ grpc::string header_code =
+ grpc_cpp_generator::GetHeaderPrologue(file, generator_parameters) +
+ grpc_cpp_generator::GetHeaderIncludes(file, generator_parameters) +
+ grpc_cpp_generator::GetHeaderServices(file, generator_parameters) +
+ grpc_cpp_generator::GetHeaderEpilogue(file, generator_parameters);
+ std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> header_output(
+ context->Open(file_name + ".grpc.pb.h"));
+ grpc::protobuf::io::CodedOutputStream header_coded_out(
+ header_output.get());
+ header_coded_out.WriteRaw(header_code.data(), header_code.size());
+
+ grpc::string source_code =
+ grpc_cpp_generator::GetSourcePrologue(file, generator_parameters) +
+ grpc_cpp_generator::GetSourceIncludes(file, generator_parameters) +
+ grpc_cpp_generator::GetSourceServices(file, generator_parameters) +
+ grpc_cpp_generator::GetSourceEpilogue(file, generator_parameters);
+ std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> source_output(
+ context->Open(file_name + ".grpc.pb.cc"));
+ grpc::protobuf::io::CodedOutputStream source_coded_out(
+ source_output.get());
+ source_coded_out.WriteRaw(source_code.data(), source_code.size());
return true;
}