void JavaCodeGenerator::generateStub(string file, TalkyUnit* unit, Interface& theInterface) { ofstream ofs(file); if (unit->currentPackage != "") { ofs << "package " << unit->currentPackage << ";" << endl; } generateImports(ofs); ofs << "public abstract class " + theInterface.name + "Stub {" << endl; ofs << "protected abstract DataOutputStream begin();" << endl; ofs << "protected abstract void end();" << endl; for (int i = 0; i < theInterface.functions.size(); i++) { ofs << "public void " + theInterface.functions[i]->name + "(" + getParamListString(theInterface.functions[i]) + ") throws Exception{" << endl; ofs << "DataOutputStream dos = begin();" << endl; ofs << "dos.write(" << i << ");" << endl; for (int j = 0; j < theInterface.functions[i]->params.size(); j++) { serializeField(ofs, *(theInterface.functions[i]->params[j])); } ofs << "end();" << endl; ofs << "}" << endl; } ofs << "}" << endl; ofs.close(); }
void GoGenerator::serializeFields( StructDefType* t ) { for (auto it:t->members_) { serializeField(it->type_,it->name_,"this.P__"); goFile_<<std::endl; } }
void JavaCodeGenerator::generate(TalkyUnit* unit, string path) { fs::path dir(path); //package if (unit->currentPackage != "") { string packagePath = unit->currentPackage; // std::replace(packagePath.begin(), packagePath.end(), ".", "/"); boost::replace_all(packagePath, ".", "/"); dir += "/" + packagePath; cout << "final path:" << dir << endl; boost::filesystem::create_directories(dir); } if (!fs::exists(dir)) { cout << "java generator output dir does not exist:" << dir << endl; exit(-1); } dir = fs::canonical(dir); path = dir.native(); cout << "generating java source to:" << path << endl; map<string, Definition*>& definitions = unit->definitions; for ( map<string, Definition*>::iterator it = definitions.begin(); it != definitions.end(); ++it ) { Definition* definition = it->second; string name = definition->name; DefinitionType type = definition->getType(); if (type == DFT_ENUM) { ofstream ofs(path + "/" + name + ".java"); if (unit->currentPackage != "") { ofs << "package " << unit->currentPackage << ";" << endl; } ofs << "public class " << name << "{" << endl; Enum& theEnum = *dynamic_cast<Enum*>(definition); for (int i = 0; i < theEnum.members.size(); i++) { ofs << "public final static int " << theEnum.members[i] << "=" << i << ";" << endl; } ofs << "public final static int MAX_VALUE=" << theEnum.members.size() << ";" << endl; ofs << "public static String toString(byte value){" << endl; for (int i = 0; i < theEnum.members.size(); i++) { ofs << "if(value == " << theEnum.members[i] << "){" << endl; ofs << "return \"" << theEnum.members[i] << "\";" << endl; ofs << "}" << endl; } ofs << "return null;" << endl; ofs << "}" << endl; ofs << "public static int toValue(String name){" << endl; for (int i = 0; i < theEnum.members.size(); i++) { ofs << "if(name.equals(\"" << theEnum.members[i] << "\")){" << endl; ofs << "return " << theEnum.members[i] << ";" << endl; ofs << "}" << endl; } ofs << "return -1;" << endl; ofs << "}" << endl; ofs << "}" << endl; ofs.close(); } else if (type == DFT_STRUCTURE) { ofstream ofs(path + "/" + name + ".java"); if (unit->currentPackage != "") { ofs << "package " << unit->currentPackage << ";" << endl; } generateImports(ofs); ofs << "public class " << name << "{" << endl; Structure& theStructure = *dynamic_cast<Structure*>(definition); std::vector<TypeDeclaration*>& fields = theStructure.members; for (int i = 0; i < fields.size(); i++) { TypeDeclaration& theField = *fields[i]; string dataTypeName = getTypeName(theField); ofs << "public " << dataTypeName << " " << theField.name << ";" << endl; } //serializer ofs << "public void serialize(DataOutputStream dos) throws Exception{" << endl; //mark fields that need serialization int fieldMarkSize = (fields.size() + 7) / 8; ofs << "FieldMark fm = new FieldMark(" << fieldMarkSize << ");" << endl; for (int i = 0; i < fields.size(); i++) { TypeDeclaration& theField = *fields[i]; if (theField.declarationType == DLT_ARRAY || theField.declarationType == DLT_BYTE_ARRAY) { //fm.mark(name == null || name.length == 0 ? false : true); ofs << "fm.mark(" << theField.name << " != null && " << theField.name << ".length > 0);" << endl; } else if (theField.declarationType == DLT_USER) { ofs << "fm.mark(true);" << endl; } else if (theField.declarationType == DLT_PRIMITIVE) { if (theField.dataType == DT_INT64 || theField.dataType == DT_UINT64 || theField.dataType == DT_DOUBLE || theField.dataType == DT_FLOAT || theField.dataType == DT_INT32 || theField.dataType == DT_UINT32 || theField.dataType == DT_INT16 || theField.dataType == DT_UINT16 || theField.dataType == DT_INT8) { ofs << "fm.mark(" << theField.name << " != 0);" << endl; } else if (theField.dataType == DT_BOOL) { ofs << "fm.mark(true);" << endl; } else if (theField.dataType == DT_STRING) { ofs << "fm.mark(" << theField.name << " != null && " << theField.name << ".length() > 0);" << endl; } } } // serialize the field mark ofs << "dos.write(fm.getData());" << endl; //actual serilization code for (int i = 0; i < fields.size(); i++) { TypeDeclaration& theField = *fields[i]; ofs << "if(fm.isMarked(" + __ITOA(i) + ")){" << endl; serializeField(ofs, theField); ofs << "}" << endl; } // ofs << "}" << endl; ofs << "}" << endl; //deserializer ofs << "public void deserialize(DataInputStream dis) throws Exception{" << endl; ofs << "FieldMark fm = new FieldMark(" << fieldMarkSize << ");" << endl; ofs << "dis.read(fm.getData());" << endl; for (int i = 0; i < fields.size(); i++) { TypeDeclaration& theField = *fields[i]; ofs << "if(fm.readMark()){" << endl; deserializeField(ofs, theField); ofs << "}" << endl; } ofs << "}" << endl; ofs << "}" << endl; ofs.close(); } else if (type == DFT_INTERFACE) { Interface& theInterface = *dynamic_cast<Interface*>(definition); generateProxy(path + "/" + name + "Proxy" + ".java", unit, theInterface); generateStub(path + "/" + name + "Stub" + ".java", unit, theInterface); generateDispatcher(path + "/" + name + "Dispatcher" + ".java", unit, theInterface); } } }
void GoGenerator::generateStruct() { if (program_->structs_.defs_.empty()) return; for(auto& it :program_->structs_.defs_) { if(it->fileName_!=program_->fileName_) { //包含头文件 不生成代码 continue; } std::string name=program_->outputDir_+it->name_+".go"; goFile_.open(name.c_str()); goFile_<<indent()<<"package "<<"rpc"<<std::endl; ///struct //fingerprint goFile_<<std::endl; goFile_<<indent()<<"const "<<it->name_<<"_"<<"strFingerprint=\""<<md5(it->getFingerPrint())<<"\""<<std::endl; goFile_<<indent()<<"type "<<it->name_<<" struct{"<<std::endl; indent_up(); //属性 for(auto& inner:it->members_) { goFile_<<indent()<<setInitialUpper(inner->name_)<<" "<<typeName(inner->type_)<<" `name:\""<<inner->name_<<"\"`"<<std::endl; } indent_down(); goFile_<<indent()<<"}" <<std::endl; //struct id goFile_<<indent()<<"func (this *"<<it->name_<<") GetFingerprint() string{"<<std::endl; indent_up(); goFile_<<indent()<<"return "<<it->name_<<"_"<<"strFingerprint"<<std::endl; indent_down(); goFile_<<"}"<<std::endl; //struct 序列化 goFile_<<indent()<<"func (this *"<<it->name_<<") Serialize( P__ IProtocol){"<<std::endl; indent_up(); for(auto& inner:it->members_) { serializeField(inner->type_,"this."+setInitialUpper(inner->name_),"P__"); goFile_<<std::endl; } indent_down(); goFile_<<"}"<<std::endl; //struct 反序列化 goFile_<<indent()<<"func (this *"<<it->name_<<") DeSerialize( P__ IProtocol) bool{"<<std::endl; indent_up(); for(auto& inner:it->members_) { deSerializeField(inner->type_,"this."+setInitialUpper(inner->name_)); goFile_<<std::endl; } goFile_<<indent()<<"return true"<<std::endl; indent_down(); goFile_<<"}"<<std::endl; goFile_<<std::endl; goFile_.close(); } }
void GoGenerator::serializeField( DefType* t ,const std::string& fieldName ,const std::string& inner) { if (t->is_struct()) { goFile_<<indent()<<fieldName<<".Serialize("<<inner<<")"<<std::endl; } else if (t->is_simple_type()) { SimpleDefType* s=(SimpleDefType*)t; switch (s->t_) { case SimpleDefType::boolType : { goFile_<<indent()<<inner<<".WriteBool("<<fieldName<<")"<<std::endl; break; } case SimpleDefType::uint8Type : { goFile_<<indent()<<inner<<".WriteUInt8("<<fieldName<<")"<<std::endl; break; } case SimpleDefType::int8Type : { goFile_<<indent()<<inner<<".WriteInt8("<<fieldName<<")"<<std::endl; break; } case SimpleDefType::uint16Type : { goFile_<<indent()<<inner<<".WriteUInt16("<<fieldName<<")"<<std::endl; break; } case SimpleDefType::int16Type : { goFile_<<indent()<<inner<<".WriteInt16("<<fieldName<<")"<<std::endl; break; } case SimpleDefType::uint32Type : { goFile_<<indent()<<inner<<".WriteUInt32("<<fieldName<<")"<<std::endl; break; } case SimpleDefType::int32Type : { goFile_<<indent()<<inner<<".WriteInt32("<<fieldName<<")"<<std::endl; break; } case SimpleDefType::int64Type : { goFile_<<indent()<<inner<<".WriteInt64("<<fieldName<<")"<<std::endl; break; } case SimpleDefType::floatType : { goFile_<<indent()<<inner<<".WriteFloat("<<fieldName<<")"<<std::endl; break; } case SimpleDefType::stringType : { goFile_<<indent()<<inner<<".WriteString("<<fieldName<<")"<<std::endl; break; } } } else if(t->is_array()) { goFile_<<indent()<<inner<<".WriteUInt16(uint16(len("<<fieldName<<")))"<<std::endl; goFile_<<indent()<<"for _ ,v := range "<<fieldName<<" {"<<std::endl; indent_up(); serializeField(((ArrayDefType*)t)->valueDef_,"v",inner); indent_down(); goFile_<<indent()<<"}"<<std::endl; }else if (t->is_enum()) { goFile_<<indent()<<inner<<".WriteInt16("<<fieldName<<")"<<std::endl; }else if(t->is_map()) { } }