@@ -37,12 +37,14 @@ namespace grpc {
3737namespace {
3838bool ClientStreaming (const RPCCall *method) {
3939 const Value *val = method->attributes .Lookup (" streaming" );
40- return val != nullptr && (val->constant == " client" || val->constant == " bidi" );
40+ return val != nullptr &&
41+ (val->constant == " client" || val->constant == " bidi" );
4142}
4243
4344bool ServerStreaming (const RPCCall *method) {
4445 const Value *val = method->attributes .Lookup (" streaming" );
45- return val != nullptr && (val->constant == " server" || val->constant == " bidi" );
46+ return val != nullptr &&
47+ (val->constant == " server" || val->constant == " bidi" );
4648}
4749
4850void FormatImports (std::stringstream &ss, const Imports &imports) {
@@ -103,9 +105,10 @@ class BaseGenerator {
103105 protected:
104106 BaseGenerator (const Parser &parser, const Namer::Config &config,
105107 const std::string &path, const Version &version)
106- : parser_{parser},
107- namer_{WithFlagOptions (config, parser.opts , path), Keywords (version)},
108- version_{version} {}
108+ : parser_{ parser },
109+ namer_{ WithFlagOptions (config, parser.opts , path), Keywords (version) },
110+ version_{ version },
111+ path_ (path) {}
109112
110113 protected:
111114 std::string ModuleForFile (const std::string &file) const {
@@ -115,15 +118,34 @@ class BaseGenerator {
115118 return module ;
116119 }
117120
118- template <typename T>
119- std::string ModuleFor (const T *def) const {
121+ template <typename T> std::string ModuleFor (const T *def) const {
120122 if (parser_.opts .one_file ) return ModuleForFile (def->file );
121123 return namer_.NamespacedType (*def);
122124 }
123125
126+ std::string NamespaceDir (const Parser &parser, const std::string &path,
127+ const Namespace &ns, const bool dasherize) {
128+ EnsureDirExists (path);
129+ if (parser.opts .one_file ) return path;
130+ std::string namespace_dir = path; // Either empty or ends in separator.
131+ auto &namespaces = ns.components ;
132+ for (auto it = namespaces.begin (); it != namespaces.end (); ++it) {
133+ namespace_dir +=
134+ !dasherize ? *it : ConvertCase (*it, Case::kDasher , Case::kUpperCamel );
135+ namespace_dir += kPathSeparator ;
136+ EnsureDirExists (namespace_dir);
137+ }
138+ return namespace_dir;
139+ }
140+
141+ std::string NamespaceDir (const Namespace &ns, const bool dasherize) {
142+ return NamespaceDir (parser_, path_, ns, dasherize);
143+ }
144+
124145 const Parser &parser_;
125146 const IdlNamer namer_;
126147 const Version version_;
148+ const std::string &path_;
127149};
128150
129151class StubGenerator : public BaseGenerator {
@@ -135,14 +157,18 @@ class StubGenerator : public BaseGenerator {
135157 bool Generate () {
136158 Imports imports;
137159 std::stringstream stub;
160+ std::string ns_name{};
138161 for (const ServiceDef *service : parser_.services_ .vec ) {
139162 Generate (stub, service, &imports);
163+ ns_name = NamespaceDir (*service->defined_namespace , false );
140164 }
141165
166+ std::string sanitized_suffix{ parser_.opts .grpc_filename_suffix };
167+ std::replace (sanitized_suffix.begin (), sanitized_suffix.end (), ' .' , ' _' );
142168 std::string filename =
143- namer_. config_ . output_path +
169+ ns_name + kPathSeparator +
144170 StripPath (StripExtension (parser_.file_being_parsed_ )) + " _grpc" +
145- parser_. opts . grpc_filename_suffix + namer_.config_ .filename_extension ;
171+ sanitized_suffix + namer_.config_ .filename_extension ;
146172
147173 return SaveStub (filename, imports, stub.str ());
148174 }
@@ -247,16 +273,20 @@ class ServiceGenerator : public BaseGenerator {
247273 << ' \n ' ;
248274 }
249275
276+ std::string ns_name{};
250277 for (const ServiceDef *service : parser_.services_ .vec ) {
251278 GenerateStub (ss, service, &imports);
252279 GenerateServicer (ss, service, &imports);
253280 GenerateRegister (ss, service, &imports);
281+ ns_name = NamespaceDir (*service->defined_namespace , false );
254282 }
255283
284+ std::string sanitized_suffix{ parser_.opts .grpc_filename_suffix };
285+ std::replace (sanitized_suffix.begin (), sanitized_suffix.end (), ' .' , ' _' );
256286 std::string filename =
257- namer_. config_ . output_path +
287+ ns_name + kPathSeparator +
258288 StripPath (StripExtension (parser_.file_being_parsed_ )) + " _grpc" +
259- parser_. opts . grpc_filename_suffix + namer_.config_ .filename_extension ;
289+ sanitized_suffix + namer_.config_ .filename_extension ;
260290
261291 return SaveService (filename, imports, ss.str ());
262292 }
@@ -365,13 +395,13 @@ class ServiceGenerator : public BaseGenerator {
365395
366396bool Generate (const Parser &parser, const std::string &path,
367397 const Version &version) {
368- ServiceGenerator generator{parser, path, version};
398+ ServiceGenerator generator{ parser, path, version };
369399 return generator.Generate ();
370400}
371401
372402bool GenerateStub (const Parser &parser, const std::string &path,
373403 const Version &version) {
374- StubGenerator generator{parser, path, version};
404+ StubGenerator generator{ parser, path, version };
375405 return generator.Generate ();
376406}
377407
0 commit comments