TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
BnetServiceGenerator Class Reference

#include <BnetServiceGenerator.h>

Public Member Functions

 BnetServiceGenerator (const pb::ServiceDescriptor *descriptor, const pbcpp::Options &options)
 
 ~BnetServiceGenerator ()
 
void GenerateDeclarations (pb::io::Printer *printer)
 
void GenerateDescriptorInitializer (pb::io::Printer *printer, int index)
 
void GenerateImplementation (pb::io::Printer *printer)
 

Private Member Functions

void GenerateInterface (pb::io::Printer *printer)
 
void GenerateClientMethodSignatures (pb::io::Printer *printer)
 
void GenerateServerMethodSignatures (pb::io::Printer *printer)
 
void GenerateClientMethodImplementations (pb::io::Printer *printer)
 
void GenerateServerCallMethod (pb::io::Printer *printer)
 
void GenerateServerImplementations (pb::io::Printer *printer)
 
std::uint32_t HashServiceName (std::string const &name)
 
 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS (BnetServiceGenerator)
 

Private Attributes

const pb::ServiceDescriptordescriptor_
 
std::map< std::string,
std::string > 
vars_
 

Constructor & Destructor Documentation

BnetServiceGenerator::BnetServiceGenerator ( const pb::ServiceDescriptor descriptor,
const pbcpp::Options &  options 
)
14  : descriptor_(descriptor)
15 {
16  vars_["classname"] = descriptor_->name();
17  vars_["full_name"] = descriptor_->full_name();
18  if (options.dllexport_decl.empty())
19  vars_["dllexport"] = "";
20  else
21  vars_["dllexport"] = options.dllexport_decl + " ";
22 
23  vars_["original_hash"] = " typedef std::integral_constant<uint32, 0x" + pb::ToUpper(pb::ToHex(HashServiceName(descriptor_->options().GetExtension(Battlenet::original_fully_qualified_descriptor_name)))) + "u> OriginalHash;\n";
24  vars_["name_hash"] = " typedef std::integral_constant<uint32, 0x" + pb::ToUpper(pb::ToHex(HashServiceName(descriptor_->full_name()))) + "u> NameHash;\n";
25 }
string ToUpper(const string &s)
Definition: strutil.h:152
const string & name() const
extern::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::ServiceOptions,::google::protobuf::internal::StringTypeTraits, 9, false > original_fully_qualified_descriptor_name
Definition: service_options.pb.h:44
const string & full_name() const
LIBPROTOBUF_EXPORT string ToHex(uint64 num)
std::uint32_t HashServiceName(std::string const &name)
Definition: BnetServiceGenerator.cpp:309
const pb::ServiceDescriptor * descriptor_
Definition: BnetServiceGenerator.h:80
std::map< std::string, std::string > vars_
Definition: BnetServiceGenerator.h:81
const ServiceOptions & options() const

+ Here is the call graph for this function:

BnetServiceGenerator::~BnetServiceGenerator ( )
27 { }

Member Function Documentation

void BnetServiceGenerator::GenerateClientMethodImplementations ( pb::io::Printer *  printer)
private
160 {
161  for (int i = 0; i < descriptor_->method_count(); i++)
162  {
163  pb::MethodDescriptor const* method = descriptor_->method(i);
164  if (!method->options().HasExtension(Battlenet::method_id))
165  continue;
166 
167  std::map<std::string, std::string> sub_vars;
168  sub_vars["classname"] = vars_["classname"];
169  sub_vars["name"] = method->name();
170  sub_vars["full_name"] = descriptor_->name() + "." + method->name();
171  sub_vars["method_id"] = pb::SimpleItoa(method->options().GetExtension(Battlenet::method_id));
172  sub_vars["input_type"] = pbcpp::ClassName(method->input_type(), true);
173  sub_vars["output_type"] = pbcpp::ClassName(method->output_type(), true);
174  sub_vars["input_type_name"] = method->input_type()->full_name();
175 
176  if (method->output_type()->name() != "NO_RESPONSE")
177  {
178  printer->Print(sub_vars,
179  "void $classname$::$name$($input_type$ const* request, std::function<void($output_type$ const*)> responseCallback) {\n"
180  " TC_LOG_DEBUG(\"service.protobuf\", \"%s Server called client method $full_name$($input_type_name${ %s })\",\n"
181  " GetCallerInfo().c_str(), request->ShortDebugString().c_str());\n"
182  " std::function<void(MessageBuffer)> callback = [responseCallback](MessageBuffer buffer) -> void {\n"
183  " $output_type$ response;\n"
184  " if (response.ParseFromArray(buffer.GetReadPointer(), buffer.GetActiveSize()))\n"
185  " responseCallback(&response);\n"
186  " };\n"
187  " SendRequest(service_hash_, $method_id$, request, std::move(callback));\n"
188  "}\n"
189  "\n");
190  }
191  else
192  {
193  printer->Print(sub_vars,
194  "void $classname$::$name$($input_type$ const* request) { \n"
195  " TC_LOG_DEBUG(\"service.protobuf\", \"%s Server called client method $full_name$($input_type_name${ %s })\",\n"
196  " GetCallerInfo().c_str(), request->ShortDebugString().c_str());\n"
197  " SendRequest(service_hash_, $method_id$, request);\n"
198  "}\n"
199  "\n");
200  }
201  }
202 }
Definition: descriptor.h:918
extern::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MethodOptions,::google::protobuf::internal::PrimitiveTypeTraits< ::google::protobuf::uint32 >, 13, false > method_id
Definition: method_options.pb.h:44
const MethodOptions & options() const
const Descriptor * output_type() const
const string & name() const
const string & name() const
const Descriptor * input_type() const
const string & full_name() const
const string & name() const
LIBPROTOBUF_EXPORT string SimpleItoa(int i)
const pb::ServiceDescriptor * descriptor_
Definition: BnetServiceGenerator.h:80
std::map< std::string, std::string > vars_
Definition: BnetServiceGenerator.h:81
string ClassName(const Descriptor *descriptor, bool qualified)
const MethodDescriptor * method(int index) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void BnetServiceGenerator::GenerateClientMethodSignatures ( pb::io::Printer *  printer)
private
84 {
85  for (int i = 0; i < descriptor_->method_count(); i++)
86  {
87  pb::MethodDescriptor const* method = descriptor_->method(i);
88  if (!method->options().HasExtension(Battlenet::method_id))
89  continue;
90 
91  std::map<std::string, std::string> sub_vars;
92  sub_vars["name"] = method->name();
93  sub_vars["full_name"] = descriptor_->name() + "." + method->name();
94  sub_vars["method_id"] = pb::SimpleItoa(method->options().GetExtension(Battlenet::method_id));
95  sub_vars["input_type"] = pbcpp::ClassName(method->input_type(), true);
96  sub_vars["output_type"] = pbcpp::ClassName(method->output_type(), true);
97  sub_vars["input_type_name"] = method->input_type()->full_name();
98 
99  if (method->output_type()->name() != "NO_RESPONSE")
100  printer->Print(sub_vars, "void $name$($input_type$ const* request, std::function<void($output_type$ const*)> responseCallback);\n");
101  else
102  printer->Print(sub_vars, "void $name$($input_type$ const* request);\n");
103  }
104 }
Definition: descriptor.h:918
extern::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MethodOptions,::google::protobuf::internal::PrimitiveTypeTraits< ::google::protobuf::uint32 >, 13, false > method_id
Definition: method_options.pb.h:44
const MethodOptions & options() const
const Descriptor * output_type() const
const string & name() const
const string & name() const
const Descriptor * input_type() const
const string & full_name() const
const string & name() const
LIBPROTOBUF_EXPORT string SimpleItoa(int i)
const pb::ServiceDescriptor * descriptor_
Definition: BnetServiceGenerator.h:80
string ClassName(const Descriptor *descriptor, bool qualified)
const MethodDescriptor * method(int index) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void BnetServiceGenerator::GenerateDeclarations ( pb::io::Printer *  printer)
30 {
31  GenerateInterface(printer);
32 }
void GenerateInterface(pb::io::Printer *printer)
Definition: BnetServiceGenerator.cpp:34

+ Here is the call graph for this function:

void BnetServiceGenerator::GenerateDescriptorInitializer ( pb::io::Printer *  printer,
int  index 
)
129 {
130  std::map<std::string, std::string> vars;
131  vars["classname"] = descriptor_->name();
132  vars["index"] = pb::SimpleItoa(index);
133 
134  printer->Print(vars, "$classname$_descriptor_ = file->service($index$);\n");
135 }
const string & name() const
LIBPROTOBUF_EXPORT string SimpleItoa(int i)
const pb::ServiceDescriptor * descriptor_
Definition: BnetServiceGenerator.h:80

+ Here is the call graph for this function:

void BnetServiceGenerator::GenerateImplementation ( pb::io::Printer *  printer)
140 {
141  printer->Print(vars_,
142  "$classname$::$classname$(bool use_original_hash) : service_hash_(use_original_hash ? OriginalHash::value : NameHash::value) {\n"
143  "}\n"
144  "\n"
145  "$classname$::~$classname$() {\n"
146  "}\n"
147  "\n"
148  "google::protobuf::ServiceDescriptor const* $classname$::descriptor() {\n"
149  " protobuf_AssignDescriptorsOnce();\n"
150  " return $classname$_descriptor_;\n"
151  "}\n"
152  "\n");
153 
155  GenerateServerCallMethod(printer);
157 }
void GenerateServerCallMethod(pb::io::Printer *printer)
Definition: BnetServiceGenerator.cpp:204
void GenerateClientMethodImplementations(pb::io::Printer *printer)
Definition: BnetServiceGenerator.cpp:159
void GenerateServerImplementations(pb::io::Printer *printer)
Definition: BnetServiceGenerator.cpp:273
std::map< std::string, std::string > vars_
Definition: BnetServiceGenerator.h:81

+ Here is the call graph for this function:

void BnetServiceGenerator::GenerateInterface ( pb::io::Printer *  printer)
private
35 {
36  printer->Print(vars_,
37  "class $dllexport$$classname$ : public ServiceBase\n"
38  "{\n"
39  " public:\n"
40  "\n"
41  " explicit $classname$(bool use_original_hash);\n"
42  " virtual ~$classname$();\n"
43  "\n"
44  "$original_hash$"
45  "$name_hash$");
46 
47  printer->Indent();
48 
49  printer->Print(vars_,
50  "\n"
51  "static google::protobuf::ServiceDescriptor const* descriptor();\n"
52  "\n"
53  "// client methods --------------------------------------------------\n"
54  "\n");
55 
57 
58  printer->Print(
59  "// server methods --------------------------------------------------\n"
60  "\n"
61  "void CallServerMethod(uint32 token, uint32 methodId, MessageBuffer buffer) override final;\n"
62  "\n");
63 
64  printer->Outdent();
65 
66  printer->Print(" protected:\n ");
67 
68  printer->Indent();
69 
71 
72  printer->Outdent();
73 
74  printer->Print(vars_,
75  "\n"
76  " private:\n"
77  " uint32 service_hash_;\n"
78  "\n"
79  " GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$);\n"
80  "};\n");
81 }
void GenerateClientMethodSignatures(pb::io::Printer *printer)
Definition: BnetServiceGenerator.cpp:83
void GenerateServerMethodSignatures(pb::io::Printer *printer)
Definition: BnetServiceGenerator.cpp:106
std::map< std::string, std::string > vars_
Definition: BnetServiceGenerator.h:81

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void BnetServiceGenerator::GenerateServerCallMethod ( pb::io::Printer *  printer)
private
205 {
206  printer->Print(vars_,
207  "void $classname$::CallServerMethod(uint32 token, uint32 methodId, MessageBuffer buffer) {\n"
208  " switch(methodId) {\n");
209 
210  for (int i = 0; i < descriptor_->method_count(); i++)
211  {
212  pb::MethodDescriptor const* method = descriptor_->method(i);
213  if (!method->options().HasExtension(Battlenet::method_id))
214  continue;
215 
216  std::map<std::string, std::string> sub_vars;
217  sub_vars["name"] = method->name();
218  sub_vars["full_name"] = descriptor_->name() + "." + method->name();
219  sub_vars["method_id"] = pb::SimpleItoa(method->options().GetExtension(Battlenet::method_id));
220  sub_vars["input_type"] = pbcpp::ClassName(method->input_type(), true);
221  sub_vars["output_type"] = pbcpp::ClassName(method->output_type(), true);
222  sub_vars["input_type_name"] = method->input_type()->full_name();
223  sub_vars["output_type_name"] = method->output_type()->full_name();
224 
225  printer->Print(sub_vars,
226  " case $method_id$: {\n"
227  " $input_type$ request;\n"
228  " if (!request.ParseFromArray(buffer.GetReadPointer(), buffer.GetActiveSize())) {\n"
229  " TC_LOG_DEBUG(\"service.protobuf\", \"%s Failed to parse request for $full_name$ server method call.\", GetCallerInfo().c_str());\n"
230  " SendResponse(service_hash_, $method_id$, token, ERROR_RPC_MALFORMED_REQUEST);\n"
231  " return;\n"
232  " }\n"
233  "\n"
234  );
235 
236  if (method->output_type()->name() != "NO_RESPONSE")
237  {
238  printer->Print(sub_vars,
239  " $output_type$ response;\n"
240  " uint32 status = Handle$name$(&request, &response);\n"
241  " TC_LOG_DEBUG(\"service.protobuf\", \"%s Client called server method $full_name$($input_type_name${ %s }) returned $output_type_name${ %s } status %u.\",\n"
242  " GetCallerInfo().c_str(), request.ShortDebugString().c_str(), response.ShortDebugString().c_str(), status);\n"
243  " if (!status)\n"
244  " SendResponse(service_hash_, $method_id$, token, &response);\n"
245  " else\n"
246  " SendResponse(service_hash_, $method_id$, token, status);\n");
247  }
248  else
249  {
250  printer->Print(sub_vars,
251  " uint32 status = Handle$name$(&request);\n"
252  " TC_LOG_DEBUG(\"service.protobuf\", \"%s Client called server method $full_name$($input_type_name${ %s }) status %u.\",\n"
253  " GetCallerInfo().c_str(), request.ShortDebugString().c_str(), status);\n"
254  " if (status)\n"
255  " SendResponse(service_hash_, $method_id$, token, status);\n");
256  }
257 
258  printer->Print(sub_vars,
259  " break;\n"
260  " }\n");
261  }
262 
263  printer->Print(vars_,
264  " default:\n"
265  " TC_LOG_ERROR(\"service.protobuf\", \"Bad method id %u.\", methodId);\n"
266  " SendResponse(service_hash_, methodId, token, ERROR_RPC_INVALID_METHOD);\n"
267  " break;\n"
268  " }\n"
269  "}\n"
270  "\n");
271 }
Definition: descriptor.h:918
extern::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MethodOptions,::google::protobuf::internal::PrimitiveTypeTraits< ::google::protobuf::uint32 >, 13, false > method_id
Definition: method_options.pb.h:44
const MethodOptions & options() const
const Descriptor * output_type() const
const string & name() const
const string & name() const
const Descriptor * input_type() const
const string & full_name() const
const string & name() const
LIBPROTOBUF_EXPORT string SimpleItoa(int i)
const pb::ServiceDescriptor * descriptor_
Definition: BnetServiceGenerator.h:80
std::map< std::string, std::string > vars_
Definition: BnetServiceGenerator.h:81
string ClassName(const Descriptor *descriptor, bool qualified)
const MethodDescriptor * method(int index) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void BnetServiceGenerator::GenerateServerImplementations ( pb::io::Printer *  printer)
private
274 {
275  for (int i = 0; i < descriptor_->method_count(); i++)
276  {
277  pb::MethodDescriptor const* method = descriptor_->method(i);
278  if (!method->options().HasExtension(Battlenet::method_id))
279  continue;
280 
281  std::map<std::string, std::string> sub_vars;
282  sub_vars["classname"] = vars_["classname"];
283  sub_vars["name"] = method->name();
284  sub_vars["full_name"] = descriptor_->name() + "." + method->name();
285  sub_vars["input_type"] = pbcpp::ClassName(method->input_type(), true);
286  sub_vars["output_type"] = pbcpp::ClassName(method->output_type(), true);
287 
288  if (method->output_type()->name() != "NO_RESPONSE")
289  {
290  printer->Print(sub_vars, "uint32 $classname$::Handle$name$($input_type$ const* request, $output_type$* response) {\n"
291  " TC_LOG_ERROR(\"service.protobuf\", \"%s Client tried to call not implemented method $full_name$({ %s })\",\n"
292  " GetCallerInfo().c_str(), request->ShortDebugString().c_str());\n"
293  " return ERROR_RPC_NOT_IMPLEMENTED;\n"
294  "}\n"
295  "\n");
296  }
297  else
298  {
299  printer->Print(sub_vars, "uint32 $classname$::Handle$name$($input_type$ const* request) {\n"
300  " TC_LOG_ERROR(\"service.protobuf\", \"%s Client tried to call not implemented method $full_name$({ %s })\",\n"
301  " GetCallerInfo().c_str(), request->ShortDebugString().c_str());\n"
302  " return ERROR_RPC_NOT_IMPLEMENTED;\n"
303  "}\n"
304  "\n");
305  }
306  }
307 }
Definition: descriptor.h:918
extern::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MethodOptions,::google::protobuf::internal::PrimitiveTypeTraits< ::google::protobuf::uint32 >, 13, false > method_id
Definition: method_options.pb.h:44
const MethodOptions & options() const
const Descriptor * output_type() const
const string & name() const
const string & name() const
const Descriptor * input_type() const
const string & name() const
const pb::ServiceDescriptor * descriptor_
Definition: BnetServiceGenerator.h:80
std::map< std::string, std::string > vars_
Definition: BnetServiceGenerator.h:81
string ClassName(const Descriptor *descriptor, bool qualified)
const MethodDescriptor * method(int index) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void BnetServiceGenerator::GenerateServerMethodSignatures ( pb::io::Printer *  printer)
private
107 {
108  for (int i = 0; i < descriptor_->method_count(); i++)
109  {
110  pb::MethodDescriptor const* method = descriptor_->method(i);
111  if (!method->options().HasExtension(Battlenet::method_id))
112  continue;
113 
114  std::map<std::string, std::string> sub_vars;
115  sub_vars["name"] = method->name();
116  sub_vars["input_type"] = pbcpp::ClassName(method->input_type(), true);
117  sub_vars["output_type"] = pbcpp::ClassName(method->output_type(), true);
118 
119  if (method->output_type()->name() != "NO_RESPONSE")
120  printer->Print(sub_vars, "virtual uint32 Handle$name$($input_type$ const* request, $output_type$* response);\n");
121  else
122  printer->Print(sub_vars, "virtual uint32 Handle$name$($input_type$ const* request);\n");
123  }
124 }
Definition: descriptor.h:918
extern::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MethodOptions,::google::protobuf::internal::PrimitiveTypeTraits< ::google::protobuf::uint32 >, 13, false > method_id
Definition: method_options.pb.h:44
const MethodOptions & options() const
const Descriptor * output_type() const
const string & name() const
const Descriptor * input_type() const
const string & name() const
const pb::ServiceDescriptor * descriptor_
Definition: BnetServiceGenerator.h:80
string ClassName(const Descriptor *descriptor, bool qualified)
const MethodDescriptor * method(int index) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

BnetServiceGenerator::GOOGLE_DISALLOW_EVIL_CONSTRUCTORS ( BnetServiceGenerator  )
private
std::uint32_t BnetServiceGenerator::HashServiceName ( std::string const name)
private
310 {
311  std::uint32_t hash = 0x811C9DC5;
312  for (std::size_t i = 0; i < name.length(); ++i)
313  {
314  hash ^= name[i];
315  hash *= 0x1000193;
316  }
317 
318  return hash;
319 }
#define hash
Definition: private_namespace.h:186
unsigned int uint32_t
Definition: stdint.h:80

+ Here is the caller graph for this function:

Member Data Documentation

const pb::ServiceDescriptor* BnetServiceGenerator::descriptor_
private
std::map<std::string, std::string> BnetServiceGenerator::vars_
private

The documentation for this class was generated from the following files: