123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539 |
- /**
- * Tencent is pleased to support the open source community by making Tars available.
- *
- * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
- *
- * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * https://opensource.org/licenses/BSD-3-Clause
- *
- * Unless required by applicable law or agreed to in writing, software distributed
- * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations under the License.
- */
- #include "tars2python.h"
- // begin modify
- #include "util/tc_md5.h"
- #include "util/tc_file.h"
- #include "util/tc_common.h"
- #include <string>
- // end modify
- #define TAB g_parse->getTab()
- #define INC_TAB g_parse->incTab()
- #define DEL_TAB g_parse->delTab()
- const string MAP_PREFIX = "mapcls_";
- const string VEC_PREFIX = "vctcls_";
- string Tars2Python::generatePython(const EnumPtr &pPtr, const std::string &sNamespace)
- {
- std::ostringstream s;
- s << TAB << "class " << pPtr->getId() << ":" << endl;
- INC_TAB;
- int nenum = -1;
- vector<TypeIdPtr>& member = pPtr->getAllMemberPtr();
- for (size_t i = 0; i < member.size(); i++)
- {
- if (member[i]->hasDefault())
- {
- nenum = tars::TC_Common::strto<int>(member[i]->def());
- }
- else
- {
- nenum++;
- }
- s << TAB << member[i]->getId()<< " = " << tars::TC_Common::tostr(nenum) << ";" << endl;
- }
- DEL_TAB;
- return s.str();
- }
- std::string Tars2Python::toFunctionName(const TypeIdPtr & pPtr, const string & sName)
- {
- BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr->getTypePtr());
- if (bPtr)
- {
- switch (bPtr->kind())
- {
- case Builtin::KindBool : return "tarscore.boolean";
- case Builtin::KindString: return "tarscore.string";
- case Builtin::KindByte: return "tarscore.int8";
- case Builtin::KindShort: return "tarscore." + string((bPtr->isUnsigned()?"uint8":"int16"));
- case Builtin::KindInt: return "tarscore." + string((bPtr->isUnsigned()?"uint16":"int32"));
- case Builtin::KindLong: return "tarscore." + string((bPtr->isUnsigned()?"uint32":"int64"));
- case Builtin::KindFloat: return "tarscore.float";
- case Builtin::KindDouble: return "tarscore.double";
- default: assert(false);
- }
- }
- StructPtr sPtr = StructPtr::dynamicCast(pPtr->getTypePtr());
- if (sPtr)
- {
- return sPtr->getId();
- }
- EnumPtr ePtr = EnumPtr::dynamicCast(pPtr->getTypePtr());
- if (ePtr)
- {
- return "tarscore.int32";
- }
- VectorPtr vPtr = VectorPtr::dynamicCast(pPtr->getTypePtr());
- if (vPtr)
- {
- BuiltinPtr vbPtr = BuiltinPtr::dynamicCast(vPtr->getTypePtr());
- if (vbPtr && vbPtr->kind() == Builtin::KindByte)
- {
- return "tarscore.bytes";
- }
- return "value." + VEC_PREFIX + sName;
- }
- MapPtr mPtr = MapPtr::dynamicCast(pPtr->getTypePtr());
- if (mPtr)
- {
- return "value." + MAP_PREFIX + sName;
- }
- assert(false);
- return "";
- }
- string Tars2Python::getDefault(const TypeIdPtr & pPtr, const std::string &sDefault, const std::string & sCurStruct)
- {
- BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr->getTypePtr());
- if (bPtr)
- {
- switch (bPtr->kind())
- {
- case Builtin::KindBool : return sDefault.empty()?"True": (sDefault == "true"?"True":"False");
- case Builtin::KindString : return "\"" + tars::TC_Common::replace(sDefault, "\"", "\\\"") + "\"";
- case Builtin::KindByte :
- case Builtin::KindShort :
- case Builtin::KindInt :
- case Builtin::KindLong : return sDefault.empty()?"0":sDefault;
- case Builtin::KindFloat :
- case Builtin::KindDouble : return sDefault.empty()?"0.0":sDefault;
- default : assert(false);
- }
- }
- VectorPtr vPtr = VectorPtr::dynamicCast(pPtr->getTypePtr());
- if (vPtr)
- {
- BuiltinPtr vbPtr = BuiltinPtr::dynamicCast(vPtr->getTypePtr());
- if (vbPtr && vbPtr->kind() == Builtin::KindByte)
- {
- return "bytes()";
- }
- return sCurStruct + "." + VEC_PREFIX + pPtr->getId() + "()";
- }
- EnumPtr ePtr = EnumPtr::dynamicCast(pPtr->getTypePtr());
- if (ePtr)
- {
- string sid = ePtr->getSid();
- size_t pos = sid.find_last_of(":");
- return sDefault.empty()?"0":(sid.substr((pos == string::npos)?0:pos + 1) + "." + sDefault);
- }
- StructPtr sPtr = StructPtr::dynamicCast(pPtr->getTypePtr());
- if (sPtr)
- {
- return sPtr->getId() + "()";
- }
- MapPtr mPtr = MapPtr::dynamicCast(pPtr->getTypePtr());
- if (mPtr)
- {
- return sCurStruct + "." + MAP_PREFIX + pPtr->getId() + "()";
- }
- assert(false);
- return sDefault;
- }
- string Tars2Python::tostrEnum(const EnumPtr &pPtr)
- {
- return "tarscore.int8";
- }
- string Tars2Python::makeDataType(const TypePtr & pPtr)
- {
- BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr);
- if (bPtr)
- {
- switch (bPtr->kind())
- {
- case Builtin::KindBool : return "tarscore.boolean";
- case Builtin::KindString: return "tarscore.string";
- case Builtin::KindByte: return "tarscore.int8";
- case Builtin::KindShort: return "tarscore." + string((bPtr->isUnsigned()?"uint8":"int16"));
- case Builtin::KindInt: return "tarscore." + string((bPtr->isUnsigned()?"uint16":"int32"));
- case Builtin::KindLong: return "tarscore." + string((bPtr->isUnsigned()?"uint32":"int64"));
- case Builtin::KindFloat: return "tarscore.float";
- case Builtin::KindDouble: return "tarscore.double";
- default: assert(false);
- }
- }
- VectorPtr vPtr = VectorPtr::dynamicCast(pPtr);
- if (vPtr)
- {
- BuiltinPtr vbPtr = BuiltinPtr::dynamicCast(vPtr->getTypePtr());
- if (vbPtr && vbPtr->kind() == Builtin::KindByte)
- {
- return "tarscore.bytes";
- }
- return "tarscore.vctclass(" + makeDataType(vPtr->getTypePtr()) + ")";
- }
- EnumPtr ePtr = EnumPtr::dynamicCast(pPtr);
- if(ePtr) return tostrEnum(ePtr);
-
- StructPtr sPtr = StructPtr::dynamicCast(pPtr);
- if (sPtr)
- {
- return sPtr->getId();
- }
- MapPtr mPtr = MapPtr::dynamicCast(pPtr);
- if (mPtr)
- {
- return "tarscore.mapclass(" + makeDataType(mPtr->getLeftTypePtr()) + ", " + makeDataType(mPtr->getRightTypePtr()) + ")";
- }
- assert(false);
- return "";
- }
- string Tars2Python::generatePython(const StructPtr & pPtr, const NamespacePtr & nPtr)
- {
- std::ostringstream s;
- vector<string> key = pPtr->getKey();
- vector<TypeIdPtr> & member = pPtr->getAllMemberPtr();
- s << TAB << "class " << pPtr->getId() << "(tarscore.struct):"<< endl;
- INC_TAB;
- s << TAB << "__tars_class__ = \"" << nPtr->getId() << "." << pPtr->getId() << "\";" << endl;
- for (size_t i = 0, len = member.size(); i < len; i++)
- {
- VectorPtr vPtr = VectorPtr::dynamicCast(member[i]->getTypePtr());
- if (vPtr)
- {
- BuiltinPtr vbPtr = BuiltinPtr::dynamicCast(vPtr->getTypePtr());
- if (vbPtr && vbPtr->kind() == Builtin::KindByte) continue;
- string st = makeDataType(member[i]->getTypePtr());
- s << TAB << VEC_PREFIX << member[i]->getId() << " = " << st << ";" << endl;
- }
- MapPtr mPtr = MapPtr::dynamicCast(member[i]->getTypePtr());
- if (mPtr)
- {
- string st = makeDataType(member[i]->getTypePtr());
- s << TAB << MAP_PREFIX << member[i]->getId() << " = " << st << ";" << endl;
- }
- }
- s << TAB << endl;
- s << TAB << "def __init__(self):" << endl;
- INC_TAB;
- for (size_t i = 0; i < member.size(); i++)
- {
- s << TAB << "self." << member[i]->getId() << " = " << getDefault(member[i], member[i]->def(), pPtr->getId()) << ";" << endl;
- }
- DEL_TAB;
- s << TAB << endl;
- s << TAB << "@staticmethod" << endl;
- s << TAB << "def writeTo(oos, value):" << endl;
- INC_TAB;
- for (size_t i = 0; i < member.size(); i++)
- {
- std::string sFuncName = toFunctionName(member[i], member[i]->getId());
- s << TAB << "oos.write(" << sFuncName << ", " << member[i]->getTag() << ", value." << member[i]->getId() << ");" << endl;
- }
- DEL_TAB;
- s << TAB << endl;
- s << TAB << "@staticmethod" << endl;
- s << TAB << "def readFrom(ios):" << endl;
- INC_TAB;
- s << TAB << "value = " << pPtr->getId() << "();" << endl;
- for (size_t i = 0; i < member.size(); i++)
- {
- std::string sFuncName = toFunctionName(member[i], member[i]->getId());
- s << TAB << "value." << member[i]->getId() << "= ios.read(" << sFuncName << ", " << member[i]->getTag()
- << ", " << (member[i]->isRequire()?"True":"False") << ", value." << member[i]->getId() << ");" << endl;
- }
- s << TAB << "return value;" << endl;
- DEL_TAB;
- DEL_TAB;
- return s.str();
- }
- string Tars2Python::makeParams(const OperationPtr &pPtr)
- {
- ostringstream str;
- vector<ParamDeclPtr>& vParamDecl = pPtr->getAllParamDeclPtr();
- for (size_t i = 0; i < vParamDecl.size(); i++)
- {
- if (vParamDecl[i]->isOut()) continue;
- str << vParamDecl[i]->getTypeIdPtr()->getId() << ", ";
- }
- str << "context = ServantProxy.mapcls_context()";
- return str.str();
- }
- #if 0
- std::string Tars2Python::innerDataType(const TypeIdPtr & pPtr)
- {
- BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr->getTypePtr());
- if (bPtr)
- {
- switch (bPtr->kind())
- {
- case Builtin::KindBool : return "tarscore.boolean";
- case Builtin::KindString: return "tarscore.string";
- case Builtin::KindByte: return "tarscore.int8";
- case Builtin::KindShort: return "tarscore." + string((bPtr->isUnsigned()?"uint8":"int16"));
- case Builtin::KindInt: return "tarscore." + string((bPtr->isUnsigned()?"uint16":"int32"));
- case Builtin::KindLong: return "tarscore." + string((bPtr->isUnsigned()?"uint32":"int64"));
- case Builtin::KindFloat: return "tarscore.float";
- case Builtin::KindDouble: return "tarscore.double";
- default: assert(false);
- }
- }
- StructPtr sPtr = StructPtr::dynamicCast(pPtr->getTypePtr());
- if (sPtr)
- {
- return sPtr->getId();
- }
- EnumPtr ePtr = EnumPtr::dynamicCast(pPtr->getTypePtr());
- if (ePtr)
- {
- return "tarscore.int32";
- }
- VectorPtr vPtr = VectorPtr::dynamicCast(pPtr->getTypePtr());
- if (vPtr)
- {
- BuiltinPtr vbPtr = BuiltinPtr::dynamicCast(vPtr->getTypePtr());
- if (vbPtr && vbPtr->kind() == Builtin::KindByte)
- {
- return "tarscore.bytes";
- }
- return "tarscore.vctclass(" + innerDataType(vPtr->getTypePtr()) + ")";
- }
- MapPtr mPtr = MapPtr::dynamicCast(pPtr->getTypePtr());
- if (mPtr)
- {
- return "tarscore.mapclass(" + innerDataType() + ")";
- }
- assert(false);
- return "";
- }
- #endif
- string Tars2Python::makeOperations(const OperationPtr &pPtr)
- {
- ostringstream str;
- vector<ParamDeclPtr>& vParamDecl = pPtr->getAllParamDeclPtr();
- str << TAB << "oos = tarscore.TarsOutputStream();" << endl;
- for(size_t i = 0; i < vParamDecl.size(); i++)
- {
- if(vParamDecl[i]->isOut()) continue;
- str << TAB << "oos.write(" << makeDataType(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) << ", " << (i + 1) << ", " << vParamDecl[i]->getTypeIdPtr()->getId() << ");" << endl;
- }
- str << endl;
- str << TAB << "rsp = self.tars_invoke(ServantProxy.TARSNORMAL, \"" << pPtr->getId() << "\", oos.getBuffer(), context, None);" << endl << endl;
- if(vParamDecl.size() > 0 || pPtr->getReturnPtr()->getTypePtr())
- {
- str << TAB << "ios = tarscore.TarsInputStream(rsp.sBuffer);" << endl;
- string ret;
- if (pPtr->getReturnPtr()->getTypePtr())
- {
- str << TAB << "ret = ios.read(" << makeDataType(pPtr->getReturnPtr()->getTypePtr()) << ", 0, True);" << endl;
- ret += "ret, ";
- }
- for(size_t i = 0; i < vParamDecl.size(); i++)
- {
- if(!vParamDecl[i]->isOut()) continue;
- str << TAB << vParamDecl[i]->getTypeIdPtr()->getId() << " = ios.read(" << makeDataType(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) << ", " << (i + 1) << ", True);" << endl;
- ret += vParamDecl[i]->getTypeIdPtr()->getId() + ", ";
- }
- str << endl;
- if (!ret.empty())
- {
- str << TAB << "return (" << ret.substr(0, ret.find_last_of(",")) << ");" << endl;
- }
- }
- return str.str();
- }
- string Tars2Python::generatePython(const InterfacePtr &pPtr)
- {
- std::ostringstream str;
- str << "#proxy for client" << endl;
- str << TAB << "class " << pPtr->getId() << "Proxy(ServantProxy):" << endl;
- INC_TAB;
- vector<OperationPtr>& vOperation = pPtr->getAllOperationPtr();
- for(size_t i = 0; i < vOperation.size(); i++)
- {
- str << TAB << "def " << vOperation[i]->getId() << "(self, " << makeParams(vOperation[i]) << "):" << endl;
- INC_TAB;
- str << makeOperations(vOperation[i]) << endl;
- DEL_TAB;
- }
- DEL_TAB;
- return str.str();
- }
- string Tars2Python::generatePython(const NamespacePtr &pPtr)
- {
- std::ostringstream str;
- /*
- vector<ConstPtr> &cs = pPtr->getAllConstPtr();
- for (size_t i = 0; i < cs.size(); i++)
- {
- str << generatePython(cs[i], pPtr->getId()) << endl;
- }
- str << endl;
- */
- vector<EnumPtr> & es = pPtr->getAllEnumPtr();
- for (size_t i = 0; i < es.size(); i++)
- {
- str << generatePython(es[i], pPtr->getId()) << endl;
- }
- vector<StructPtr> & ss = pPtr->getAllStructPtr();
- for (size_t i = 0; i < ss.size(); i++)
- {
- str << generatePython(ss[i], pPtr) << endl;
- }
- vector<InterfacePtr> & is = pPtr->getAllInterfacePtr();
- for(size_t i = 0; i < is.size(); i++)
- {
- str << generatePython(is[i]) << endl << endl;
- }
- return str.str();
- }
- void Tars2Python::generatePython(const ContextPtr &pPtr)
- {
- vector<NamespacePtr> namespaces = pPtr->getNamespaces();
- for(size_t i = 0; i < namespaces.size(); i++)
- {
- std::ostringstream str;
- str << "from tars.core import tarscore;" << endl;
- str << "from tars.__rpc import ServantProxy;" << endl;
- vector<string> include = pPtr->getIncludes();
- for(size_t j = 0; j < include.size(); j++)
- {
- set<string> vec;
- getNamespace(tars::TC_File::excludeFileExt(include[j]) + ".tars", vec);
- for (set<string>::iterator it = vec.begin(); it != vec.end(); it++)
- {
- str << "from " << _packagePrefix << *it << "." << tars::TC_File::excludeFileExt(include[j]) << " import *;" << endl;
- }
- }
- str << endl << endl;
- str << generatePython(namespaces[i]) << endl;
- string sPath = getFilePath() + FILE_SEP + namespaces[i]->getId() + FILE_SEP;
- string sFileName = sPath + tars::TC_File::excludeFileExt(tars::TC_File::extractFileName(pPtr->getFileName())) + ".py";
- tars::TC_File::makeDirRecursive(sPath);
- tars::TC_File::save2file(sFileName, str.str());
- }
- makePackages();
- }
- void Tars2Python::getNamespace(const string & sFile, set<string> & vec)
- {
- g_parse->parse(sFile);
- vector<ContextPtr> contexts = g_parse->getContexts();
- for (size_t i = 0; i < contexts.size(); i++)
- {
- if(sFile != contexts[i]->getFileName()) continue;
- vector<NamespacePtr> namespaces = contexts[i]->getNamespaces();
- for (size_t j = 0; j < namespaces.size(); j++)
- vec.insert(namespaces[j]->getId());
- }
- }
- void Tars2Python::createFile(const string &file)
- {
- std::vector<ContextPtr> contexts = g_parse->getContexts();
- for(size_t i = 0; i < contexts.size(); i++)
- {
- if(file == contexts[i]->getFileName())
- {
- generatePython(contexts[i]);
- }
- }
- }
- void Tars2Python::makePackages()
- {
- string root = _packagePrefix.substr(0, _packagePrefix.find("."));
- vector<string> files;
- tars::TC_File::listDirectory(_baseDir + "/" + root, files, true);
- files.push_back(_baseDir + "/" + root);
- for (size_t i = 0; i < files.size(); i++)
- {
- if (tars::TC_File::isFileExist(files[i], S_IFDIR) == true)
- {
- tars::TC_File::save2file(files[i] + FILE_SEP + "__init__.py", "");
- }
- }
- }
- string Tars2Python::getFilePath() const
- {
- return _baseDir + FILE_SEP + tars::TC_Common::replace(_packagePrefix, ".", FILE_SEP);
- }
|