void RpcGenerator::generateSentExternalBlock(const string &variableName, const string &channelName, const google::protobuf::Descriptor *descriptor, google::protobuf::io::Printer &printer) const { for(int i=0; i< descriptor->field_count(); i++) { const FieldDescriptor *field = descriptor->field(i); if (field->type() == FieldDescriptor::TYPE_MESSAGE) { string messageTypeName = field->message_type()->full_name(); if (messageTypeName.find("external.") == 0) { string externalClass = externalTypeToClass(messageTypeName); std::ostringstream stream; stream << "obj" << i; string var = stream.str(); printer.Print("if ($variableName$->has_$fieldName$()) {\n", "variableName", variableName, "fieldName", field->lowercase_name()); printer.Indent(); printer.Print("$externalClass$ *$var$ = ", "externalClass", externalClass, "var", var); printer.Print("$variableName$->$fieldName$().get();\n", "variableName", variableName, "fieldName", field->lowercase_name()); printer.Print("if ($var$) {\n", "var", var); printer.Indent(); printer.Print("$externalClass$Serializer serializer($var$);\n", "externalClass", externalClass, "var", var); printer.Print("size_t size = serializer.size();\n"); std::map<string, string> variables; variables["channelName"] = channelName; printer.Print("std::vector<unsigned char> data(size);\n"); this->generateErrorCheck("serializer.serialize(&data[0], size)", variables, printer, "$channelName$->setErrorString(\"Serialization failed\");return;\n"); variables.clear(); variables["channelName"] = channelName; // Send the size first this->generateErrorCheck("$channelName$->send(size)", variables, printer); this->generateErrorCheck("$channelName$->send(&data[0], size)", variables, printer); printer.Outdent(); printer.Print("}\n"); printer.Outdent(); printer.Print("}\n"); } } } }
void RpcGenerator::generateReceiveExternalBlock(const string &variableName, const string &channelName, const google::protobuf::Descriptor *descriptor, google::protobuf::io::Printer &printer) const { bool hasExternalTypes = false; string code; io::StringOutputStream stream(&code); io::Printer tmpPrinter(&stream, '$'); for(int i=0; i< descriptor->field_count(); i++) { const FieldDescriptor *field = descriptor->field(i); if (field->type() == FieldDescriptor::TYPE_MESSAGE) { string messageTypeName = field->message_type()->full_name(); if (messageTypeName.find("external.") == 0) { hasExternalTypes = true; string externalClass = externalTypeToClass(messageTypeName); std::ostringstream objStream; objStream << "obj" << i; string objVar = objStream.str(); std::ostringstream deserializerStream; deserializerStream << "deserializer" << i; string deserializerVar = deserializerStream.str(); std::ostringstream dataStream; dataStream << "data" << i; string dataVar = dataStream.str(); tmpPrinter.Print("if ($variableName$->has_$fieldName$()) {\n", "variableName", "tmp", "fieldName", field->lowercase_name()); tmpPrinter.Indent(); tmpPrinter.Print("::ProtoCall::Runtime::RpcVoidData $data$;\n", "data", dataVar); std::map<string, string> variables; variables["var"] = dataVar; variables["channelName"] = channelName; this->generateErrorCheck("$channelName$->receive(&$var$)", variables, tmpPrinter); tmpPrinter.Print("$externalClass$ *$objVar$ = tmp->$field$().get();\n", "externalClass", externalClass, "objVar", objVar, "field", field->lowercase_name()); tmpPrinter.Print("bool allocated = false;\n"); tmpPrinter.Print("if (!$objVar$) {\n", "objVar", objVar); tmpPrinter.Indent(); tmpPrinter.Print("$objVar$ = new $externalClass$();\n", "objVar", objVar, "externalClass", externalClass); tmpPrinter.Print("allocated = true;\n"); tmpPrinter.Outdent(); tmpPrinter.Print("}\n"); tmpPrinter.Print("$externalClass$Deserializer $deserializerVar$($objVar$);\n", "externalClass", externalClass, "deserializerVar", deserializerVar, "objVar", objVar); variables["deserializerVar"] = deserializerVar; this->generateErrorCheck("$deserializerVar$.deserialize($var$.data(), $var$.size())", variables, tmpPrinter, "$channelName$->setErrorString(\"Deserialization failed\");return;\n"); variables.clear(); variables["var"] = objVar; variables["channelName"] = channelName; variables["objVar"] = objVar; tmpPrinter.Print("if (allocated)\n"); tmpPrinter.Indent(); tmpPrinter.Print("tmp->mutable_$field$()->set_allocated($objVar$);\n", "field", field->lowercase_name(), "objVar", objVar); tmpPrinter.Outdent(); tmpPrinter.Outdent(); tmpPrinter.Print("}\n"); } } } if (hasExternalTypes) { printer.Print("::google::protobuf::Message *mutableRequest " "= const_cast< google::protobuf::Message *>($variableName$);\n", "variableName", variableName); printer.Print("$inputType$ *tmp =" "static_cast<$inputType$ *>(mutableRequest);\n", "inputType", descriptor->name()); printer.Print(code.c_str()); } }