auser-poolparty 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (353) hide show
  1. data/VERSION.yml +1 -1
  2. data/examples/monitored_cloud.rb +1 -1
  3. data/examples/thrift/thrift_example.rb +1 -1
  4. data/lib/proto/command_interface_handler.rb +1 -1
  5. data/vendor/gems/thrift/CHANGES +35 -0
  6. data/vendor/gems/thrift/CONTRIBUTORS +77 -0
  7. data/vendor/gems/thrift/DISCLAIMER +6 -0
  8. data/vendor/gems/thrift/LICENSE +202 -0
  9. data/vendor/gems/thrift/Makefile.am +28 -0
  10. data/vendor/gems/thrift/NEWS +79 -0
  11. data/vendor/gems/thrift/NOTICE +26 -0
  12. data/vendor/gems/thrift/README +137 -0
  13. data/vendor/gems/thrift/aclocal/ax_boost_base.m4 +198 -0
  14. data/vendor/gems/thrift/aclocal/ax_javac_and_java.m4 +107 -0
  15. data/vendor/gems/thrift/aclocal/ax_lib_event.m4 +194 -0
  16. data/vendor/gems/thrift/aclocal/ax_lib_zlib.m4 +173 -0
  17. data/vendor/gems/thrift/aclocal/ax_signed_right_shift.m4 +127 -0
  18. data/vendor/gems/thrift/aclocal/ax_thrift_internal.m4 +39 -0
  19. data/vendor/gems/thrift/bootstrap.sh +35 -0
  20. data/vendor/gems/thrift/cleanup.sh +58 -0
  21. data/vendor/gems/thrift/compiler/cpp/Makefile.am +136 -0
  22. data/vendor/gems/thrift/compiler/cpp/README +39 -0
  23. data/vendor/gems/thrift/compiler/cpp/src/generate/t_cocoa_generator.cc +2331 -0
  24. data/vendor/gems/thrift/compiler/cpp/src/generate/t_cpp_generator.cc +3003 -0
  25. data/vendor/gems/thrift/compiler/cpp/src/generate/t_csharp_generator.cc +1700 -0
  26. data/vendor/gems/thrift/compiler/cpp/src/generate/t_erl_generator.cc +932 -0
  27. data/vendor/gems/thrift/compiler/cpp/src/generate/t_generator.cc +173 -0
  28. data/vendor/gems/thrift/compiler/cpp/src/generate/t_generator.h +321 -0
  29. data/vendor/gems/thrift/compiler/cpp/src/generate/t_hs_generator.cc +1445 -0
  30. data/vendor/gems/thrift/compiler/cpp/src/generate/t_html_generator.cc +637 -0
  31. data/vendor/gems/thrift/compiler/cpp/src/generate/t_java_generator.cc +3069 -0
  32. data/vendor/gems/thrift/compiler/cpp/src/generate/t_ocaml_generator.cc +1673 -0
  33. data/vendor/gems/thrift/compiler/cpp/src/generate/t_oop_generator.h +77 -0
  34. data/vendor/gems/thrift/compiler/cpp/src/generate/t_perl_generator.cc +1812 -0
  35. data/vendor/gems/thrift/compiler/cpp/src/generate/t_php_generator.cc +2281 -0
  36. data/vendor/gems/thrift/compiler/cpp/src/generate/t_py_generator.cc +2310 -0
  37. data/vendor/gems/thrift/compiler/cpp/src/generate/t_rb_generator.cc +1114 -0
  38. data/vendor/gems/thrift/compiler/cpp/src/generate/t_st_generator.cc +1071 -0
  39. data/vendor/gems/thrift/compiler/cpp/src/generate/t_xsd_generator.cc +354 -0
  40. data/vendor/gems/thrift/compiler/cpp/src/globals.h +117 -0
  41. data/vendor/gems/thrift/compiler/cpp/src/main.cc +1207 -0
  42. data/vendor/gems/thrift/compiler/cpp/src/main.h +103 -0
  43. data/vendor/gems/thrift/compiler/cpp/src/md5.c +381 -0
  44. data/vendor/gems/thrift/compiler/cpp/src/md5.h +91 -0
  45. data/vendor/gems/thrift/compiler/cpp/src/parse/t_base_type.h +137 -0
  46. data/vendor/gems/thrift/compiler/cpp/src/parse/t_const.h +59 -0
  47. data/vendor/gems/thrift/compiler/cpp/src/parse/t_const_value.h +121 -0
  48. data/vendor/gems/thrift/compiler/cpp/src/parse/t_container.h +56 -0
  49. data/vendor/gems/thrift/compiler/cpp/src/parse/t_doc.h +51 -0
  50. data/vendor/gems/thrift/compiler/cpp/src/parse/t_enum.h +59 -0
  51. data/vendor/gems/thrift/compiler/cpp/src/parse/t_enum_value.h +64 -0
  52. data/vendor/gems/thrift/compiler/cpp/src/parse/t_field.h +150 -0
  53. data/vendor/gems/thrift/compiler/cpp/src/parse/t_function.h +93 -0
  54. data/vendor/gems/thrift/compiler/cpp/src/parse/t_list.h +56 -0
  55. data/vendor/gems/thrift/compiler/cpp/src/parse/t_map.h +64 -0
  56. data/vendor/gems/thrift/compiler/cpp/src/parse/t_program.h +223 -0
  57. data/vendor/gems/thrift/compiler/cpp/src/parse/t_scope.h +86 -0
  58. data/vendor/gems/thrift/compiler/cpp/src/parse/t_service.h +68 -0
  59. data/vendor/gems/thrift/compiler/cpp/src/parse/t_set.h +55 -0
  60. data/vendor/gems/thrift/compiler/cpp/src/parse/t_struct.h +127 -0
  61. data/vendor/gems/thrift/compiler/cpp/src/parse/t_type.h +176 -0
  62. data/vendor/gems/thrift/compiler/cpp/src/parse/t_typedef.h +70 -0
  63. data/vendor/gems/thrift/compiler/cpp/src/platform.h +36 -0
  64. data/vendor/gems/thrift/compiler/cpp/src/thriftl.ll +303 -0
  65. data/vendor/gems/thrift/compiler/cpp/src/thrifty.yy +1140 -0
  66. data/vendor/gems/thrift/configure.ac +255 -0
  67. data/vendor/gems/thrift/contrib/fb303/LICENSE +16 -0
  68. data/vendor/gems/thrift/contrib/fb303/Makefile.am +31 -0
  69. data/vendor/gems/thrift/contrib/fb303/README +37 -0
  70. data/vendor/gems/thrift/contrib/fb303/acinclude.m4 +258 -0
  71. data/vendor/gems/thrift/contrib/fb303/aclocal/ax_boost_base.m4 +198 -0
  72. data/vendor/gems/thrift/contrib/fb303/bootstrap.sh +26 -0
  73. data/vendor/gems/thrift/contrib/fb303/configure.ac +115 -0
  74. data/vendor/gems/thrift/contrib/fb303/cpp/FacebookBase.cpp +124 -0
  75. data/vendor/gems/thrift/contrib/fb303/cpp/FacebookBase.h +103 -0
  76. data/vendor/gems/thrift/contrib/fb303/cpp/Makefile.am +84 -0
  77. data/vendor/gems/thrift/contrib/fb303/cpp/ServiceTracker.cpp +481 -0
  78. data/vendor/gems/thrift/contrib/fb303/cpp/ServiceTracker.h +215 -0
  79. data/vendor/gems/thrift/contrib/fb303/global_footer.mk +21 -0
  80. data/vendor/gems/thrift/contrib/fb303/global_header.mk +38 -0
  81. data/vendor/gems/thrift/contrib/fb303/if/fb303.thrift +112 -0
  82. data/vendor/gems/thrift/contrib/fb303/java/FacebookBase.java +103 -0
  83. data/vendor/gems/thrift/contrib/fb303/java/build.xml +84 -0
  84. data/vendor/gems/thrift/contrib/fb303/php/FacebookBase.php +89 -0
  85. data/vendor/gems/thrift/contrib/fb303/py/Makefile.am +44 -0
  86. data/vendor/gems/thrift/contrib/fb303/py/fb303/FacebookBase.py +82 -0
  87. data/vendor/gems/thrift/contrib/fb303/py/fb303_scripts/__init__.py +20 -0
  88. data/vendor/gems/thrift/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py +195 -0
  89. data/vendor/gems/thrift/contrib/fb303/py/setup.py +27 -0
  90. data/vendor/gems/thrift/contrib/thrift.el +126 -0
  91. data/vendor/gems/thrift/contrib/thrift.spec +206 -0
  92. data/vendor/gems/thrift/contrib/thrift.vim +91 -0
  93. data/vendor/gems/thrift/contrib/thrift_dump.cpp +91 -0
  94. data/vendor/gems/thrift/doc/lgpl-2.1.txt +504 -0
  95. data/vendor/gems/thrift/doc/otp-base-license.txt +20 -0
  96. data/vendor/gems/thrift/doc/thrift.bnf +96 -0
  97. data/vendor/gems/thrift/doc/thrift.tex +1057 -0
  98. data/vendor/gems/thrift/lib/Makefile.am +55 -0
  99. data/vendor/gems/thrift/lib/cocoa/README +21 -0
  100. data/vendor/gems/thrift/lib/cocoa/src/TApplicationException.h +44 -0
  101. data/vendor/gems/thrift/lib/cocoa/src/TApplicationException.m +130 -0
  102. data/vendor/gems/thrift/lib/cocoa/src/TException.h +34 -0
  103. data/vendor/gems/thrift/lib/cocoa/src/TException.m +64 -0
  104. data/vendor/gems/thrift/lib/cocoa/src/TProcessor.h +29 -0
  105. data/vendor/gems/thrift/lib/cocoa/src/TProcessorFactory.h +27 -0
  106. data/vendor/gems/thrift/lib/cocoa/src/TSharedProcessorFactory.h +27 -0
  107. data/vendor/gems/thrift/lib/cocoa/src/TSharedProcessorFactory.m +51 -0
  108. data/vendor/gems/thrift/lib/cocoa/src/protocol/TBinaryProtocol.h +51 -0
  109. data/vendor/gems/thrift/lib/cocoa/src/protocol/TBinaryProtocol.m +477 -0
  110. data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocol.h +148 -0
  111. data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolException.h +25 -0
  112. data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolException.m +23 -0
  113. data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolFactory.h +29 -0
  114. data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolUtil.h +29 -0
  115. data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolUtil.m +104 -0
  116. data/vendor/gems/thrift/lib/cocoa/src/server/TSocketServer.h +50 -0
  117. data/vendor/gems/thrift/lib/cocoa/src/server/TSocketServer.m +153 -0
  118. data/vendor/gems/thrift/lib/cocoa/src/transport/THTTPClient.h +42 -0
  119. data/vendor/gems/thrift/lib/cocoa/src/transport/THTTPClient.m +159 -0
  120. data/vendor/gems/thrift/lib/cocoa/src/transport/TNSFileHandleTransport.h +35 -0
  121. data/vendor/gems/thrift/lib/cocoa/src/transport/TNSFileHandleTransport.m +91 -0
  122. data/vendor/gems/thrift/lib/cocoa/src/transport/TNSStreamTransport.h +38 -0
  123. data/vendor/gems/thrift/lib/cocoa/src/transport/TNSStreamTransport.m +89 -0
  124. data/vendor/gems/thrift/lib/cocoa/src/transport/TSocketClient.h +32 -0
  125. data/vendor/gems/thrift/lib/cocoa/src/transport/TSocketClient.m +58 -0
  126. data/vendor/gems/thrift/lib/cocoa/src/transport/TTransport.h +36 -0
  127. data/vendor/gems/thrift/lib/cocoa/src/transport/TTransportException.h +30 -0
  128. data/vendor/gems/thrift/lib/cocoa/src/transport/TTransportException.m +43 -0
  129. data/vendor/gems/thrift/lib/cpp/Makefile.am +158 -0
  130. data/vendor/gems/thrift/lib/cpp/README +67 -0
  131. data/vendor/gems/thrift/lib/cpp/src/TLogging.h +163 -0
  132. data/vendor/gems/thrift/lib/cpp/src/TProcessor.h +53 -0
  133. data/vendor/gems/thrift/lib/cpp/src/TReflectionLocal.h +96 -0
  134. data/vendor/gems/thrift/lib/cpp/src/Thrift.cpp +148 -0
  135. data/vendor/gems/thrift/lib/cpp/src/Thrift.h +191 -0
  136. data/vendor/gems/thrift/lib/cpp/src/concurrency/Exception.h +60 -0
  137. data/vendor/gems/thrift/lib/cpp/src/concurrency/FunctionRunner.h +77 -0
  138. data/vendor/gems/thrift/lib/cpp/src/concurrency/Monitor.cpp +137 -0
  139. data/vendor/gems/thrift/lib/cpp/src/concurrency/Monitor.h +84 -0
  140. data/vendor/gems/thrift/lib/cpp/src/concurrency/Mutex.cpp +160 -0
  141. data/vendor/gems/thrift/lib/cpp/src/concurrency/Mutex.h +114 -0
  142. data/vendor/gems/thrift/lib/cpp/src/concurrency/PosixThreadFactory.cpp +314 -0
  143. data/vendor/gems/thrift/lib/cpp/src/concurrency/PosixThreadFactory.h +130 -0
  144. data/vendor/gems/thrift/lib/cpp/src/concurrency/Thread.h +125 -0
  145. data/vendor/gems/thrift/lib/cpp/src/concurrency/ThreadManager.cpp +493 -0
  146. data/vendor/gems/thrift/lib/cpp/src/concurrency/ThreadManager.h +169 -0
  147. data/vendor/gems/thrift/lib/cpp/src/concurrency/TimerManager.cpp +284 -0
  148. data/vendor/gems/thrift/lib/cpp/src/concurrency/TimerManager.h +122 -0
  149. data/vendor/gems/thrift/lib/cpp/src/concurrency/Util.cpp +55 -0
  150. data/vendor/gems/thrift/lib/cpp/src/concurrency/Util.h +100 -0
  151. data/vendor/gems/thrift/lib/cpp/src/concurrency/test/Tests.cpp +155 -0
  152. data/vendor/gems/thrift/lib/cpp/src/concurrency/test/ThreadFactoryTests.h +354 -0
  153. data/vendor/gems/thrift/lib/cpp/src/concurrency/test/ThreadManagerTests.h +379 -0
  154. data/vendor/gems/thrift/lib/cpp/src/concurrency/test/TimerManagerTests.h +155 -0
  155. data/vendor/gems/thrift/lib/cpp/src/processor/PeekProcessor.cpp +122 -0
  156. data/vendor/gems/thrift/lib/cpp/src/processor/PeekProcessor.h +77 -0
  157. data/vendor/gems/thrift/lib/cpp/src/processor/StatsProcessor.h +264 -0
  158. data/vendor/gems/thrift/lib/cpp/src/protocol/TBase64Utils.cpp +79 -0
  159. data/vendor/gems/thrift/lib/cpp/src/protocol/TBase64Utils.h +42 -0
  160. data/vendor/gems/thrift/lib/cpp/src/protocol/TBinaryProtocol.cpp +394 -0
  161. data/vendor/gems/thrift/lib/cpp/src/protocol/TBinaryProtocol.h +254 -0
  162. data/vendor/gems/thrift/lib/cpp/src/protocol/TCompactProtocol.cpp +736 -0
  163. data/vendor/gems/thrift/lib/cpp/src/protocol/TCompactProtocol.h +279 -0
  164. data/vendor/gems/thrift/lib/cpp/src/protocol/TDebugProtocol.cpp +346 -0
  165. data/vendor/gems/thrift/lib/cpp/src/protocol/TDebugProtocol.h +225 -0
  166. data/vendor/gems/thrift/lib/cpp/src/protocol/TDenseProtocol.cpp +762 -0
  167. data/vendor/gems/thrift/lib/cpp/src/protocol/TDenseProtocol.h +253 -0
  168. data/vendor/gems/thrift/lib/cpp/src/protocol/TJSONProtocol.cpp +998 -0
  169. data/vendor/gems/thrift/lib/cpp/src/protocol/TJSONProtocol.h +340 -0
  170. data/vendor/gems/thrift/lib/cpp/src/protocol/TOneWayProtocol.h +304 -0
  171. data/vendor/gems/thrift/lib/cpp/src/protocol/TProtocol.h +438 -0
  172. data/vendor/gems/thrift/lib/cpp/src/protocol/TProtocolException.h +104 -0
  173. data/vendor/gems/thrift/lib/cpp/src/protocol/TProtocolTap.h +187 -0
  174. data/vendor/gems/thrift/lib/cpp/src/server/TNonblockingServer.cpp +750 -0
  175. data/vendor/gems/thrift/lib/cpp/src/server/TNonblockingServer.h +435 -0
  176. data/vendor/gems/thrift/lib/cpp/src/server/TServer.cpp +38 -0
  177. data/vendor/gems/thrift/lib/cpp/src/server/TServer.h +213 -0
  178. data/vendor/gems/thrift/lib/cpp/src/server/TSimpleServer.cpp +118 -0
  179. data/vendor/gems/thrift/lib/cpp/src/server/TSimpleServer.h +70 -0
  180. data/vendor/gems/thrift/lib/cpp/src/server/TThreadPoolServer.cpp +217 -0
  181. data/vendor/gems/thrift/lib/cpp/src/server/TThreadPoolServer.h +79 -0
  182. data/vendor/gems/thrift/lib/cpp/src/server/TThreadedServer.cpp +243 -0
  183. data/vendor/gems/thrift/lib/cpp/src/server/TThreadedServer.h +74 -0
  184. data/vendor/gems/thrift/lib/cpp/src/transport/TBufferTransports.cpp +370 -0
  185. data/vendor/gems/thrift/lib/cpp/src/transport/TBufferTransports.h +667 -0
  186. data/vendor/gems/thrift/lib/cpp/src/transport/TFDTransport.cpp +77 -0
  187. data/vendor/gems/thrift/lib/cpp/src/transport/TFDTransport.h +73 -0
  188. data/vendor/gems/thrift/lib/cpp/src/transport/TFileTransport.cpp +953 -0
  189. data/vendor/gems/thrift/lib/cpp/src/transport/TFileTransport.h +442 -0
  190. data/vendor/gems/thrift/lib/cpp/src/transport/THttpClient.cpp +348 -0
  191. data/vendor/gems/thrift/lib/cpp/src/transport/THttpClient.h +111 -0
  192. data/vendor/gems/thrift/lib/cpp/src/transport/TServerSocket.cpp +368 -0
  193. data/vendor/gems/thrift/lib/cpp/src/transport/TServerSocket.h +76 -0
  194. data/vendor/gems/thrift/lib/cpp/src/transport/TServerTransport.h +92 -0
  195. data/vendor/gems/thrift/lib/cpp/src/transport/TShortReadTransport.h +96 -0
  196. data/vendor/gems/thrift/lib/cpp/src/transport/TSimpleFileTransport.cpp +54 -0
  197. data/vendor/gems/thrift/lib/cpp/src/transport/TSimpleFileTransport.h +41 -0
  198. data/vendor/gems/thrift/lib/cpp/src/transport/TSocket.cpp +591 -0
  199. data/vendor/gems/thrift/lib/cpp/src/transport/TSocket.h +242 -0
  200. data/vendor/gems/thrift/lib/cpp/src/transport/TSocketPool.cpp +235 -0
  201. data/vendor/gems/thrift/lib/cpp/src/transport/TSocketPool.h +191 -0
  202. data/vendor/gems/thrift/lib/cpp/src/transport/TTransport.h +224 -0
  203. data/vendor/gems/thrift/lib/cpp/src/transport/TTransportException.cpp +31 -0
  204. data/vendor/gems/thrift/lib/cpp/src/transport/TTransportException.h +117 -0
  205. data/vendor/gems/thrift/lib/cpp/src/transport/TTransportUtils.cpp +178 -0
  206. data/vendor/gems/thrift/lib/cpp/src/transport/TTransportUtils.h +287 -0
  207. data/vendor/gems/thrift/lib/cpp/src/transport/TZlibTransport.cpp +299 -0
  208. data/vendor/gems/thrift/lib/cpp/src/transport/TZlibTransport.h +219 -0
  209. data/vendor/gems/thrift/lib/cpp/thrift-nb.pc.in +30 -0
  210. data/vendor/gems/thrift/lib/cpp/thrift-z.pc.in +30 -0
  211. data/vendor/gems/thrift/lib/cpp/thrift.pc.in +29 -0
  212. data/vendor/gems/thrift/lib/csharp/Makefile.am +70 -0
  213. data/vendor/gems/thrift/lib/csharp/README +26 -0
  214. data/vendor/gems/thrift/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs +55 -0
  215. data/vendor/gems/thrift/lib/csharp/ThriftMSBuildTask/ThriftBuild.cs +242 -0
  216. data/vendor/gems/thrift/lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj +62 -0
  217. data/vendor/gems/thrift/lib/csharp/src/Collections/THashSet.cs +142 -0
  218. data/vendor/gems/thrift/lib/csharp/src/Protocol/TBase.cs +34 -0
  219. data/vendor/gems/thrift/lib/csharp/src/Protocol/TBinaryProtocol.cs +392 -0
  220. data/vendor/gems/thrift/lib/csharp/src/Protocol/TField.cs +58 -0
  221. data/vendor/gems/thrift/lib/csharp/src/Protocol/TList.cs +50 -0
  222. data/vendor/gems/thrift/lib/csharp/src/Protocol/TMap.cs +58 -0
  223. data/vendor/gems/thrift/lib/csharp/src/Protocol/TMessage.cs +58 -0
  224. data/vendor/gems/thrift/lib/csharp/src/Protocol/TMessageType.cs +31 -0
  225. data/vendor/gems/thrift/lib/csharp/src/Protocol/TProtocol.cs +87 -0
  226. data/vendor/gems/thrift/lib/csharp/src/Protocol/TProtocolException.cs +61 -0
  227. data/vendor/gems/thrift/lib/csharp/src/Protocol/TProtocolFactory.cs +29 -0
  228. data/vendor/gems/thrift/lib/csharp/src/Protocol/TProtocolUtil.cs +94 -0
  229. data/vendor/gems/thrift/lib/csharp/src/Protocol/TSet.cs +50 -0
  230. data/vendor/gems/thrift/lib/csharp/src/Protocol/TStruct.cs +42 -0
  231. data/vendor/gems/thrift/lib/csharp/src/Protocol/TType.cs +40 -0
  232. data/vendor/gems/thrift/lib/csharp/src/Server/TServer.cs +135 -0
  233. data/vendor/gems/thrift/lib/csharp/src/Server/TSimpleServer.cs +148 -0
  234. data/vendor/gems/thrift/lib/csharp/src/Server/TThreadPoolServer.cs +186 -0
  235. data/vendor/gems/thrift/lib/csharp/src/Server/TThreadedServer.cs +234 -0
  236. data/vendor/gems/thrift/lib/csharp/src/TApplicationException.cs +131 -0
  237. data/vendor/gems/thrift/lib/csharp/src/TProcessor.cs +29 -0
  238. data/vendor/gems/thrift/lib/csharp/src/Thrift.csproj +73 -0
  239. data/vendor/gems/thrift/lib/csharp/src/Thrift.sln +35 -0
  240. data/vendor/gems/thrift/lib/csharp/src/Transport/TBufferedTransport.cs +100 -0
  241. data/vendor/gems/thrift/lib/csharp/src/Transport/TServerSocket.cs +157 -0
  242. data/vendor/gems/thrift/lib/csharp/src/Transport/TServerTransport.cs +39 -0
  243. data/vendor/gems/thrift/lib/csharp/src/Transport/TSocket.cs +144 -0
  244. data/vendor/gems/thrift/lib/csharp/src/Transport/TStreamTransport.cs +103 -0
  245. data/vendor/gems/thrift/lib/csharp/src/Transport/TTransport.cs +66 -0
  246. data/vendor/gems/thrift/lib/csharp/src/Transport/TTransportException.cs +64 -0
  247. data/vendor/gems/thrift/lib/csharp/src/Transport/TTransportFactory.cs +38 -0
  248. data/vendor/gems/thrift/lib/erl/Makefile +37 -0
  249. data/vendor/gems/thrift/lib/erl/README +56 -0
  250. data/vendor/gems/thrift/lib/erl/build/beamver +59 -0
  251. data/vendor/gems/thrift/lib/erl/build/buildtargets.mk +15 -0
  252. data/vendor/gems/thrift/lib/erl/build/colors.mk +24 -0
  253. data/vendor/gems/thrift/lib/erl/build/docs.mk +12 -0
  254. data/vendor/gems/thrift/lib/erl/build/mime.types +98 -0
  255. data/vendor/gems/thrift/lib/erl/build/otp.mk +146 -0
  256. data/vendor/gems/thrift/lib/erl/build/otp_subdir.mk +85 -0
  257. data/vendor/gems/thrift/lib/erl/build/raw_test.mk +29 -0
  258. data/vendor/gems/thrift/lib/erl/include/thrift_constants.hrl +54 -0
  259. data/vendor/gems/thrift/lib/erl/include/thrift_protocol.hrl +31 -0
  260. data/vendor/gems/thrift/lib/erl/src/Makefile +116 -0
  261. data/vendor/gems/thrift/lib/erl/src/test_handler.erl +26 -0
  262. data/vendor/gems/thrift/lib/erl/src/test_service.erl +29 -0
  263. data/vendor/gems/thrift/lib/erl/src/thrift.app.src +44 -0
  264. data/vendor/gems/thrift/lib/erl/src/thrift.appup.src +1 -0
  265. data/vendor/gems/thrift/lib/erl/src/thrift_base64_transport.erl +64 -0
  266. data/vendor/gems/thrift/lib/erl/src/thrift_binary_protocol.erl +325 -0
  267. data/vendor/gems/thrift/lib/erl/src/thrift_buffered_transport.erl +180 -0
  268. data/vendor/gems/thrift/lib/erl/src/thrift_client.erl +384 -0
  269. data/vendor/gems/thrift/lib/erl/src/thrift_disk_log_transport.erl +118 -0
  270. data/vendor/gems/thrift/lib/erl/src/thrift_file_transport.erl +87 -0
  271. data/vendor/gems/thrift/lib/erl/src/thrift_framed_transport.erl +208 -0
  272. data/vendor/gems/thrift/lib/erl/src/thrift_http_transport.erl +199 -0
  273. data/vendor/gems/thrift/lib/erl/src/thrift_memory_buffer.erl +164 -0
  274. data/vendor/gems/thrift/lib/erl/src/thrift_processor.erl +188 -0
  275. data/vendor/gems/thrift/lib/erl/src/thrift_protocol.erl +356 -0
  276. data/vendor/gems/thrift/lib/erl/src/thrift_server.erl +183 -0
  277. data/vendor/gems/thrift/lib/erl/src/thrift_service.erl +25 -0
  278. data/vendor/gems/thrift/lib/erl/src/thrift_socket_server.erl +249 -0
  279. data/vendor/gems/thrift/lib/erl/src/thrift_socket_transport.erl +119 -0
  280. data/vendor/gems/thrift/lib/erl/src/thrift_transport.erl +57 -0
  281. data/vendor/gems/thrift/lib/erl/vsn.mk +1 -0
  282. data/vendor/gems/thrift/lib/hs/README +82 -0
  283. data/vendor/gems/thrift/lib/hs/Setup.lhs +23 -0
  284. data/vendor/gems/thrift/lib/hs/TODO +2 -0
  285. data/vendor/gems/thrift/lib/hs/Thrift.cabal +20 -0
  286. data/vendor/gems/thrift/lib/hs/src/Thrift.hs +111 -0
  287. data/vendor/gems/thrift/lib/hs/src/Thrift/Protocol.hs +191 -0
  288. data/vendor/gems/thrift/lib/hs/src/Thrift/Protocol/Binary.hs +147 -0
  289. data/vendor/gems/thrift/lib/hs/src/Thrift/Server.hs +65 -0
  290. data/vendor/gems/thrift/lib/hs/src/Thrift/Transport.hs +60 -0
  291. data/vendor/gems/thrift/lib/hs/src/Thrift/Transport/Handle.hs +58 -0
  292. data/vendor/gems/thrift/lib/java/Makefile.am +38 -0
  293. data/vendor/gems/thrift/lib/java/README +43 -0
  294. data/vendor/gems/thrift/lib/java/build.xml +195 -0
  295. data/vendor/gems/thrift/lib/java/ivy.xml +8 -0
  296. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/IntRangeSet.java +171 -0
  297. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TApplicationException.java +123 -0
  298. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TBase.java +66 -0
  299. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TBaseHelper.java +102 -0
  300. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TByteArrayOutputStream.java +46 -0
  301. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TDeserializer.java +94 -0
  302. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TException.java +45 -0
  303. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TFieldRequirementType.java +30 -0
  304. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TProcessor.java +32 -0
  305. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TProcessorFactory.java +39 -0
  306. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TSerializer.java +110 -0
  307. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/FieldMetaData.java +69 -0
  308. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/FieldValueMetaData.java +42 -0
  309. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/ListMetaData.java +29 -0
  310. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/MapMetaData.java +31 -0
  311. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/SetMetaData.java +29 -0
  312. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/StructMetaData.java +31 -0
  313. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TBase64Utils.java +128 -0
  314. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TBinaryProtocol.java +331 -0
  315. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java +741 -0
  316. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TField.java +48 -0
  317. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TJSONProtocol.java +927 -0
  318. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TList.java +38 -0
  319. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TMap.java +40 -0
  320. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TMessage.java +48 -0
  321. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TMessageType.java +31 -0
  322. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TProtocol.java +146 -0
  323. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TProtocolException.java +81 -0
  324. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TProtocolFactory.java +30 -0
  325. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TProtocolUtil.java +158 -0
  326. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TSet.java +42 -0
  327. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TSimpleJSONProtocol.java +384 -0
  328. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TStruct.java +36 -0
  329. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TType.java +40 -0
  330. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/THsHaServer.java +304 -0
  331. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/TNonblockingServer.java +772 -0
  332. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/TServer.java +126 -0
  333. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/TSimpleServer.java +145 -0
  334. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/TThreadPoolServer.java +271 -0
  335. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TFramedTransport.java +126 -0
  336. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/THttpClient.java +157 -0
  337. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TIOStreamTransport.java +159 -0
  338. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TMemoryBuffer.java +98 -0
  339. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TNonblockingServerSocket.java +160 -0
  340. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TNonblockingServerTransport.java +31 -0
  341. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TNonblockingSocket.java +213 -0
  342. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TNonblockingTransport.java +31 -0
  343. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TServerSocket.java +145 -0
  344. metadata +348 -37
  345. data/vendor/gems/trollop/FAQ.txt +0 -35
  346. data/vendor/gems/trollop/History.txt +0 -84
  347. data/vendor/gems/trollop/Manifest.txt +0 -7
  348. data/vendor/gems/trollop/README.txt +0 -38
  349. data/vendor/gems/trollop/Rakefile +0 -36
  350. data/vendor/gems/trollop/lib/trollop.rb +0 -695
  351. data/vendor/gems/trollop/release-script.txt +0 -13
  352. data/vendor/gems/trollop/test/test_trollop.rb +0 -957
  353. data/vendor/gems/trollop/www/index.html +0 -167
@@ -0,0 +1,2310 @@
1
+ /*
2
+ * Licensed to the Apache Software Foundation (ASF) under one
3
+ * or more contributor license agreements. See the NOTICE file
4
+ * distributed with this work for additional information
5
+ * regarding copyright ownership. The ASF licenses this file
6
+ * to you under the Apache License, Version 2.0 (the
7
+ * "License"); you may not use this file except in compliance
8
+ * with the License. You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
18
+ */
19
+
20
+ #include <string>
21
+ #include <fstream>
22
+ #include <iostream>
23
+ #include <vector>
24
+
25
+ #include <stdlib.h>
26
+ #include <sys/stat.h>
27
+ #include <sys/types.h>
28
+ #include <sstream>
29
+ #include <algorithm>
30
+ #include "t_generator.h"
31
+ #include "platform.h"
32
+ using namespace std;
33
+
34
+
35
+ /**
36
+ * Python code generator.
37
+ *
38
+ */
39
+ class t_py_generator : public t_generator {
40
+ public:
41
+ t_py_generator(
42
+ t_program* program,
43
+ const std::map<std::string, std::string>& parsed_options,
44
+ const std::string& option_string)
45
+ : t_generator(program)
46
+ {
47
+ std::map<std::string, std::string>::const_iterator iter;
48
+
49
+ iter = parsed_options.find("new_style");
50
+ gen_newstyle_ = (iter != parsed_options.end());
51
+
52
+ iter = parsed_options.find("twisted");
53
+ gen_twisted_ = (iter != parsed_options.end());
54
+
55
+ out_dir_base_ = "gen-py";
56
+ }
57
+
58
+ /**
59
+ * Init and close methods
60
+ */
61
+
62
+ void init_generator();
63
+ void close_generator();
64
+
65
+ /**
66
+ * Program-level generation functions
67
+ */
68
+
69
+ void generate_typedef (t_typedef* ttypedef);
70
+ void generate_enum (t_enum* tenum);
71
+ void generate_const (t_const* tconst);
72
+ void generate_struct (t_struct* tstruct);
73
+ void generate_xception (t_struct* txception);
74
+ void generate_service (t_service* tservice);
75
+
76
+ std::string render_const_value(t_type* type, t_const_value* value);
77
+
78
+ /**
79
+ * Struct generation code
80
+ */
81
+
82
+ void generate_py_struct(t_struct* tstruct, bool is_exception);
83
+ void generate_py_struct_definition(std::ofstream& out, t_struct* tstruct, bool is_xception=false, bool is_result=false);
84
+ void generate_py_struct_reader(std::ofstream& out, t_struct* tstruct);
85
+ void generate_py_struct_writer(std::ofstream& out, t_struct* tstruct);
86
+ void generate_py_function_helpers(t_function* tfunction);
87
+
88
+ /**
89
+ * Service-level generation functions
90
+ */
91
+
92
+ void generate_service_helpers (t_service* tservice);
93
+ void generate_service_interface (t_service* tservice);
94
+ void generate_service_client (t_service* tservice);
95
+ void generate_service_remote (t_service* tservice);
96
+ void generate_service_server (t_service* tservice);
97
+ void generate_process_function (t_service* tservice, t_function* tfunction);
98
+
99
+ /**
100
+ * Serialization constructs
101
+ */
102
+
103
+ void generate_deserialize_field (std::ofstream &out,
104
+ t_field* tfield,
105
+ std::string prefix="",
106
+ bool inclass=false);
107
+
108
+ void generate_deserialize_struct (std::ofstream &out,
109
+ t_struct* tstruct,
110
+ std::string prefix="");
111
+
112
+ void generate_deserialize_container (std::ofstream &out,
113
+ t_type* ttype,
114
+ std::string prefix="");
115
+
116
+ void generate_deserialize_set_element (std::ofstream &out,
117
+ t_set* tset,
118
+ std::string prefix="");
119
+
120
+ void generate_deserialize_map_element (std::ofstream &out,
121
+ t_map* tmap,
122
+ std::string prefix="");
123
+
124
+ void generate_deserialize_list_element (std::ofstream &out,
125
+ t_list* tlist,
126
+ std::string prefix="");
127
+
128
+ void generate_serialize_field (std::ofstream &out,
129
+ t_field* tfield,
130
+ std::string prefix="");
131
+
132
+ void generate_serialize_struct (std::ofstream &out,
133
+ t_struct* tstruct,
134
+ std::string prefix="");
135
+
136
+ void generate_serialize_container (std::ofstream &out,
137
+ t_type* ttype,
138
+ std::string prefix="");
139
+
140
+ void generate_serialize_map_element (std::ofstream &out,
141
+ t_map* tmap,
142
+ std::string kiter,
143
+ std::string viter);
144
+
145
+ void generate_serialize_set_element (std::ofstream &out,
146
+ t_set* tmap,
147
+ std::string iter);
148
+
149
+ void generate_serialize_list_element (std::ofstream &out,
150
+ t_list* tlist,
151
+ std::string iter);
152
+
153
+ void generate_python_docstring (std::ofstream& out,
154
+ t_struct* tstruct);
155
+
156
+ void generate_python_docstring (std::ofstream& out,
157
+ t_function* tfunction);
158
+
159
+ void generate_python_docstring (std::ofstream& out,
160
+ t_doc* tdoc,
161
+ t_struct* tstruct,
162
+ const char* subheader);
163
+
164
+ void generate_python_docstring (std::ofstream& out,
165
+ t_doc* tdoc);
166
+
167
+ /**
168
+ * Helper rendering functions
169
+ */
170
+
171
+ std::string py_autogen_comment();
172
+ std::string py_imports();
173
+ std::string render_includes();
174
+ std::string render_fastbinary_includes();
175
+ std::string declare_argument(t_field* tfield);
176
+ std::string render_field_default_value(t_field* tfield);
177
+ std::string type_name(t_type* ttype);
178
+ std::string function_signature(t_function* tfunction, std::string prefix="");
179
+ std::string function_signature_if(t_function* tfunction, std::string prefix="");
180
+ std::string argument_list(t_struct* tstruct);
181
+ std::string type_to_enum(t_type* ttype);
182
+ std::string type_to_spec_args(t_type* ttype);
183
+
184
+ static std::string get_real_py_module(const t_program* program) {
185
+ std::string real_module = program->get_namespace("py");
186
+ if (real_module.empty()) {
187
+ return program->get_name();
188
+ }
189
+ return real_module;
190
+ }
191
+
192
+ private:
193
+
194
+ /**
195
+ * True iff we should generate new-style classes.
196
+ */
197
+ bool gen_newstyle_;
198
+
199
+ /**
200
+ * True iff we should generate Twisted-friendly RPC services.
201
+ */
202
+ bool gen_twisted_;
203
+
204
+ /**
205
+ * File streams
206
+ */
207
+
208
+ std::ofstream f_types_;
209
+ std::ofstream f_consts_;
210
+ std::ofstream f_service_;
211
+
212
+ std::string package_dir_;
213
+
214
+ };
215
+
216
+
217
+ /**
218
+ * Prepares for file generation by opening up the necessary file output
219
+ * streams.
220
+ *
221
+ * @param tprogram The program to generate
222
+ */
223
+ void t_py_generator::init_generator() {
224
+ // Make output directory
225
+ string module = get_real_py_module(program_);
226
+ package_dir_ = get_out_dir();
227
+ while (true) {
228
+ // TODO: Do better error checking here.
229
+ MKDIR(package_dir_.c_str());
230
+ std::ofstream init_py((package_dir_+"/__init__.py").c_str());
231
+ init_py.close();
232
+ if (module.empty()) {
233
+ break;
234
+ }
235
+ string::size_type pos = module.find('.');
236
+ if (pos == string::npos) {
237
+ package_dir_ += "/";
238
+ package_dir_ += module;
239
+ module.clear();
240
+ } else {
241
+ package_dir_ += "/";
242
+ package_dir_ += module.substr(0, pos);
243
+ module.erase(0, pos+1);
244
+ }
245
+ }
246
+
247
+ // Make output file
248
+ string f_types_name = package_dir_+"/"+"ttypes.py";
249
+ f_types_.open(f_types_name.c_str());
250
+
251
+ string f_consts_name = package_dir_+"/"+"constants.py";
252
+ f_consts_.open(f_consts_name.c_str());
253
+
254
+ string f_init_name = package_dir_+"/__init__.py";
255
+ ofstream f_init;
256
+ f_init.open(f_init_name.c_str());
257
+ f_init <<
258
+ "__all__ = ['ttypes', 'constants'";
259
+ vector<t_service*> services = program_->get_services();
260
+ vector<t_service*>::iterator sv_iter;
261
+ for (sv_iter = services.begin(); sv_iter != services.end(); ++sv_iter) {
262
+ f_init << ", '" << (*sv_iter)->get_name() << "'";
263
+ }
264
+ f_init << "]" << endl;
265
+ f_init.close();
266
+
267
+ // Print header
268
+ f_types_ <<
269
+ py_autogen_comment() << endl <<
270
+ py_imports() << endl <<
271
+ render_includes() << endl <<
272
+ render_fastbinary_includes() <<
273
+ endl << endl;
274
+
275
+ f_consts_ <<
276
+ py_autogen_comment() << endl <<
277
+ py_imports() << endl <<
278
+ "from ttypes import *" << endl <<
279
+ endl;
280
+ }
281
+
282
+ /**
283
+ * Renders all the imports necessary for including another Thrift program
284
+ */
285
+ string t_py_generator::render_includes() {
286
+ const vector<t_program*>& includes = program_->get_includes();
287
+ string result = "";
288
+ for (size_t i = 0; i < includes.size(); ++i) {
289
+ result += "import " + get_real_py_module(includes[i]) + ".ttypes\n";
290
+ }
291
+ if (includes.size() > 0) {
292
+ result += "\n";
293
+ }
294
+ return result;
295
+ }
296
+
297
+ /**
298
+ * Renders all the imports necessary to use the accelerated TBinaryProtocol
299
+ */
300
+ string t_py_generator::render_fastbinary_includes() {
301
+ return
302
+ "from thrift.transport import TTransport\n"
303
+ "from thrift.protocol import TBinaryProtocol\n"
304
+ "try:\n"
305
+ " from thrift.protocol import fastbinary\n"
306
+ "except:\n"
307
+ " fastbinary = None\n";
308
+ }
309
+
310
+ /**
311
+ * Autogen'd comment
312
+ */
313
+ string t_py_generator::py_autogen_comment() {
314
+ return
315
+ std::string("#\n") +
316
+ "# Autogenerated by Thrift\n" +
317
+ "#\n" +
318
+ "# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING\n" +
319
+ "#\n";
320
+ }
321
+
322
+ /**
323
+ * Prints standard thrift imports
324
+ */
325
+ string t_py_generator::py_imports() {
326
+ return
327
+ string("from thrift.Thrift import *");
328
+ }
329
+
330
+ /**
331
+ * Closes the type files
332
+ */
333
+ void t_py_generator::close_generator() {
334
+ // Close types file
335
+ f_types_.close();
336
+ f_consts_.close();
337
+ }
338
+
339
+ /**
340
+ * Generates a typedef. This is not done in Python, types are all implicit.
341
+ *
342
+ * @param ttypedef The type definition
343
+ */
344
+ void t_py_generator::generate_typedef(t_typedef* ttypedef) {}
345
+
346
+ /**
347
+ * Generates code for an enumerated type. Done using a class to scope
348
+ * the values.
349
+ *
350
+ * @param tenum The enumeration
351
+ */
352
+ void t_py_generator::generate_enum(t_enum* tenum) {
353
+ f_types_ <<
354
+ "class " << tenum->get_name() <<
355
+ (gen_newstyle_ ? "(object)" : "") <<
356
+ ":" << endl;
357
+ indent_up();
358
+ generate_python_docstring(f_types_, tenum);
359
+
360
+ vector<t_enum_value*> constants = tenum->get_constants();
361
+ vector<t_enum_value*>::iterator c_iter;
362
+ int value = -1;
363
+ for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
364
+ if ((*c_iter)->has_value()) {
365
+ value = (*c_iter)->get_value();
366
+ } else {
367
+ ++value;
368
+ }
369
+
370
+ f_types_ <<
371
+ indent() << (*c_iter)->get_name() << " = " << value << endl;
372
+ }
373
+
374
+ indent_down();
375
+ f_types_ << endl;
376
+ }
377
+
378
+ /**
379
+ * Generate a constant value
380
+ */
381
+ void t_py_generator::generate_const(t_const* tconst) {
382
+ t_type* type = tconst->get_type();
383
+ string name = tconst->get_name();
384
+ t_const_value* value = tconst->get_value();
385
+
386
+ indent(f_consts_) << name << " = " << render_const_value(type, value);
387
+ f_consts_ << endl << endl;
388
+ }
389
+
390
+ /**
391
+ * Prints the value of a constant with the given type. Note that type checking
392
+ * is NOT performed in this function as it is always run beforehand using the
393
+ * validate_types method in main.cc
394
+ */
395
+ string t_py_generator::render_const_value(t_type* type, t_const_value* value) {
396
+ type = get_true_type(type);
397
+ std::ostringstream out;
398
+
399
+ if (type->is_base_type()) {
400
+ t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
401
+ switch (tbase) {
402
+ case t_base_type::TYPE_STRING:
403
+ out << '"' << get_escaped_string(value) << '"';
404
+ break;
405
+ case t_base_type::TYPE_BOOL:
406
+ out << (value->get_integer() > 0 ? "True" : "False");
407
+ break;
408
+ case t_base_type::TYPE_BYTE:
409
+ case t_base_type::TYPE_I16:
410
+ case t_base_type::TYPE_I32:
411
+ case t_base_type::TYPE_I64:
412
+ out << value->get_integer();
413
+ break;
414
+ case t_base_type::TYPE_DOUBLE:
415
+ if (value->get_type() == t_const_value::CV_INTEGER) {
416
+ out << value->get_integer();
417
+ } else {
418
+ out << value->get_double();
419
+ }
420
+ break;
421
+ default:
422
+ throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase);
423
+ }
424
+ } else if (type->is_enum()) {
425
+ indent(out) << value->get_integer();
426
+ } else if (type->is_struct() || type->is_xception()) {
427
+ out << type->get_name() << "(**{" << endl;
428
+ indent_up();
429
+ const vector<t_field*>& fields = ((t_struct*)type)->get_members();
430
+ vector<t_field*>::const_iterator f_iter;
431
+ const map<t_const_value*, t_const_value*>& val = value->get_map();
432
+ map<t_const_value*, t_const_value*>::const_iterator v_iter;
433
+ for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
434
+ t_type* field_type = NULL;
435
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
436
+ if ((*f_iter)->get_name() == v_iter->first->get_string()) {
437
+ field_type = (*f_iter)->get_type();
438
+ }
439
+ }
440
+ if (field_type == NULL) {
441
+ throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string();
442
+ }
443
+ out << indent();
444
+ out << render_const_value(g_type_string, v_iter->first);
445
+ out << " : ";
446
+ out << render_const_value(field_type, v_iter->second);
447
+ out << "," << endl;
448
+ }
449
+ indent_down();
450
+ indent(out) << "})";
451
+ } else if (type->is_map()) {
452
+ t_type* ktype = ((t_map*)type)->get_key_type();
453
+ t_type* vtype = ((t_map*)type)->get_val_type();
454
+ out << "{" << endl;
455
+ indent_up();
456
+ const map<t_const_value*, t_const_value*>& val = value->get_map();
457
+ map<t_const_value*, t_const_value*>::const_iterator v_iter;
458
+ for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
459
+ out << indent();
460
+ out << render_const_value(ktype, v_iter->first);
461
+ out << " : ";
462
+ out << render_const_value(vtype, v_iter->second);
463
+ out << "," << endl;
464
+ }
465
+ indent_down();
466
+ indent(out) << "}";
467
+ } else if (type->is_list() || type->is_set()) {
468
+ t_type* etype;
469
+ if (type->is_list()) {
470
+ etype = ((t_list*)type)->get_elem_type();
471
+ } else {
472
+ etype = ((t_set*)type)->get_elem_type();
473
+ }
474
+ if (type->is_set()) {
475
+ out << "set(";
476
+ }
477
+ out << "[" << endl;
478
+ indent_up();
479
+ const vector<t_const_value*>& val = value->get_list();
480
+ vector<t_const_value*>::const_iterator v_iter;
481
+ for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
482
+ out << indent();
483
+ out << render_const_value(etype, *v_iter);
484
+ out << "," << endl;
485
+ }
486
+ indent_down();
487
+ indent(out) << "]";
488
+ if (type->is_set()) {
489
+ out << ")";
490
+ }
491
+ } else {
492
+ throw "CANNOT GENERATE CONSTANT FOR TYPE: " + type->get_name();
493
+ }
494
+
495
+ return out.str();
496
+ }
497
+
498
+ /**
499
+ * Generates a python struct
500
+ */
501
+ void t_py_generator::generate_struct(t_struct* tstruct) {
502
+ generate_py_struct(tstruct, false);
503
+ }
504
+
505
+ /**
506
+ * Generates a struct definition for a thrift exception. Basically the same
507
+ * as a struct but extends the Exception class.
508
+ *
509
+ * @param txception The struct definition
510
+ */
511
+ void t_py_generator::generate_xception(t_struct* txception) {
512
+ generate_py_struct(txception, true);
513
+ }
514
+
515
+ /**
516
+ * Generates a python struct
517
+ */
518
+ void t_py_generator::generate_py_struct(t_struct* tstruct,
519
+ bool is_exception) {
520
+ generate_py_struct_definition(f_types_, tstruct, is_exception);
521
+ }
522
+
523
+ /**
524
+ * Generates a struct definition for a thrift data type.
525
+ *
526
+ * @param tstruct The struct definition
527
+ */
528
+ void t_py_generator::generate_py_struct_definition(ofstream& out,
529
+ t_struct* tstruct,
530
+ bool is_exception,
531
+ bool is_result) {
532
+
533
+ const vector<t_field*>& members = tstruct->get_members();
534
+ const vector<t_field*>& sorted_members = tstruct->get_sorted_members();
535
+ vector<t_field*>::const_iterator m_iter;
536
+
537
+ out <<
538
+ "class " << tstruct->get_name();
539
+ if (is_exception) {
540
+ out << "(Exception)";
541
+ } else if (gen_newstyle_) {
542
+ out << "(object)";
543
+ }
544
+ out <<
545
+ ":" << endl;
546
+ indent_up();
547
+ generate_python_docstring(out, tstruct);
548
+
549
+ out << endl;
550
+
551
+ /*
552
+ Here we generate the structure specification for the fastbinary codec.
553
+ These specifications have the following structure:
554
+ thrift_spec -> tuple of item_spec
555
+ item_spec -> None | (tag, type_enum, name, spec_args, default)
556
+ tag -> integer
557
+ type_enum -> TType.I32 | TType.STRING | TType.STRUCT | ...
558
+ name -> string_literal
559
+ default -> None # Handled by __init__
560
+ spec_args -> None # For simple types
561
+ | (type_enum, spec_args) # Value type for list/set
562
+ | (type_enum, spec_args, type_enum, spec_args)
563
+ # Key and value for map
564
+ | (class_name, spec_args_ptr) # For struct/exception
565
+ class_name -> identifier # Basically a pointer to the class
566
+ spec_args_ptr -> expression # just class_name.spec_args
567
+
568
+ TODO(dreiss): Consider making this work for structs with negative tags.
569
+ */
570
+
571
+ // TODO(dreiss): Look into generating an empty tuple instead of None
572
+ // for structures with no members.
573
+ // TODO(dreiss): Test encoding of structs where some inner structs
574
+ // don't have thrift_spec.
575
+ if (sorted_members.empty() || (sorted_members[0]->get_key() >= 0)) {
576
+ indent(out) << "thrift_spec = (" << endl;
577
+ indent_up();
578
+
579
+ int sorted_keys_pos = 0;
580
+ for (m_iter = sorted_members.begin(); m_iter != sorted_members.end(); ++m_iter) {
581
+
582
+ for (; sorted_keys_pos != (*m_iter)->get_key(); sorted_keys_pos++) {
583
+ indent(out) << "None, # " << sorted_keys_pos << endl;
584
+ }
585
+
586
+ indent(out) << "(" << (*m_iter)->get_key() << ", "
587
+ << type_to_enum((*m_iter)->get_type()) << ", "
588
+ << "'" << (*m_iter)->get_name() << "'" << ", "
589
+ << type_to_spec_args((*m_iter)->get_type()) << ", "
590
+ << render_field_default_value(*m_iter) << ", "
591
+ << "),"
592
+ << " # " << sorted_keys_pos
593
+ << endl;
594
+
595
+ sorted_keys_pos ++;
596
+ }
597
+
598
+ indent_down();
599
+ indent(out) << ")" << endl << endl;
600
+ } else {
601
+ indent(out) << "thrift_spec = None" << endl;
602
+ }
603
+
604
+
605
+ if (members.size() > 0) {
606
+ out <<
607
+ indent() << "def __init__(self,";
608
+
609
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
610
+ // This fills in default values, as opposed to nulls
611
+ out << " " << declare_argument(*m_iter) << ",";
612
+ }
613
+
614
+ out << "):" << endl;
615
+
616
+ indent_up();
617
+
618
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
619
+ // Initialize fields
620
+ t_type* type = (*m_iter)->get_type();
621
+ if (!type->is_base_type() && !type->is_enum() && (*m_iter)->get_value() != NULL) {
622
+ indent(out) <<
623
+ "if " << (*m_iter)->get_name() << " is " << "self.thrift_spec[" <<
624
+ (*m_iter)->get_key() << "][4]:" << endl;
625
+ indent(out) << " " << (*m_iter)->get_name() << " = " <<
626
+ render_field_default_value(*m_iter) << endl;
627
+ }
628
+ indent(out) <<
629
+ "self." << (*m_iter)->get_name() << " = " << (*m_iter)->get_name() << endl;
630
+ }
631
+
632
+ indent_down();
633
+
634
+ out << endl;
635
+ }
636
+
637
+ generate_py_struct_reader(out, tstruct);
638
+ generate_py_struct_writer(out, tstruct);
639
+
640
+ // For exceptions only, generate a __str__ method. This is
641
+ // because when raised exceptions are printed to the console, __repr__
642
+ // isn't used. See python bug #5882
643
+ if (is_exception) {
644
+ out <<
645
+ indent() << "def __str__(self):" << endl <<
646
+ indent() << " return repr(self)" << endl <<
647
+ endl;
648
+ }
649
+
650
+ // Printing utilities so that on the command line thrift
651
+ // structs look pretty like dictionaries
652
+ out <<
653
+ indent() << "def __repr__(self):" << endl <<
654
+ indent() << " L = ['%s=%r' % (key, value)" << endl <<
655
+ indent() << " for key, value in self.__dict__.iteritems()]" << endl <<
656
+ indent() << " return '%s(%s)' % (self.__class__.__name__, ', '.join(L))" << endl <<
657
+ endl;
658
+
659
+ // Equality and inequality methods that compare by value
660
+ out <<
661
+ indent() << "def __eq__(self, other):" << endl;
662
+ indent_up();
663
+ out <<
664
+ indent() << "return isinstance(other, self.__class__) and "
665
+ "self.__dict__ == other.__dict__" << endl;
666
+ indent_down();
667
+ out << endl;
668
+
669
+ out <<
670
+ indent() << "def __ne__(self, other):" << endl;
671
+ indent_up();
672
+ out <<
673
+ indent() << "return not (self == other)" << endl;
674
+ indent_down();
675
+ out << endl;
676
+
677
+ indent_down();
678
+ }
679
+
680
+ /**
681
+ * Generates the read method for a struct
682
+ */
683
+ void t_py_generator::generate_py_struct_reader(ofstream& out,
684
+ t_struct* tstruct) {
685
+ const vector<t_field*>& fields = tstruct->get_members();
686
+ vector<t_field*>::const_iterator f_iter;
687
+
688
+ indent(out) <<
689
+ "def read(self, iprot):" << endl;
690
+ indent_up();
691
+
692
+ indent(out) <<
693
+ "if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated "
694
+ "and isinstance(iprot.trans, TTransport.CReadableTransport) "
695
+ "and self.thrift_spec is not None "
696
+ "and fastbinary is not None:" << endl;
697
+ indent_up();
698
+
699
+ indent(out) <<
700
+ "fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))" << endl;
701
+ indent(out) <<
702
+ "return" << endl;
703
+ indent_down();
704
+
705
+ indent(out) <<
706
+ "iprot.readStructBegin()" << endl;
707
+
708
+ // Loop over reading in fields
709
+ indent(out) <<
710
+ "while True:" << endl;
711
+ indent_up();
712
+
713
+ // Read beginning field marker
714
+ indent(out) <<
715
+ "(fname, ftype, fid) = iprot.readFieldBegin()" << endl;
716
+
717
+ // Check for field STOP marker and break
718
+ indent(out) <<
719
+ "if ftype == TType.STOP:" << endl;
720
+ indent_up();
721
+ indent(out) <<
722
+ "break" << endl;
723
+ indent_down();
724
+
725
+ // Switch statement on the field we are reading
726
+ bool first = true;
727
+
728
+ // Generate deserialization code for known cases
729
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
730
+ if (first) {
731
+ first = false;
732
+ out <<
733
+ indent() << "if ";
734
+ } else {
735
+ out <<
736
+ indent() << "elif ";
737
+ }
738
+ out << "fid == " << (*f_iter)->get_key() << ":" << endl;
739
+ indent_up();
740
+ indent(out) << "if ftype == " << type_to_enum((*f_iter)->get_type()) << ":" << endl;
741
+ indent_up();
742
+ generate_deserialize_field(out, *f_iter, "self.");
743
+ indent_down();
744
+ out <<
745
+ indent() << "else:" << endl <<
746
+ indent() << " iprot.skip(ftype)" << endl;
747
+ indent_down();
748
+ }
749
+
750
+ // In the default case we skip the field
751
+ out <<
752
+ indent() << "else:" << endl <<
753
+ indent() << " iprot.skip(ftype)" << endl;
754
+
755
+ // Read field end marker
756
+ indent(out) <<
757
+ "iprot.readFieldEnd()" << endl;
758
+
759
+ indent_down();
760
+
761
+ indent(out) <<
762
+ "iprot.readStructEnd()" << endl;
763
+
764
+ indent_down();
765
+ out << endl;
766
+ }
767
+
768
+ void t_py_generator::generate_py_struct_writer(ofstream& out,
769
+ t_struct* tstruct) {
770
+ string name = tstruct->get_name();
771
+ const vector<t_field*>& fields = tstruct->get_sorted_members();
772
+ vector<t_field*>::const_iterator f_iter;
773
+
774
+ indent(out) <<
775
+ "def write(self, oprot):" << endl;
776
+ indent_up();
777
+
778
+ indent(out) <<
779
+ "if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated "
780
+ "and self.thrift_spec is not None "
781
+ "and fastbinary is not None:" << endl;
782
+ indent_up();
783
+
784
+ indent(out) <<
785
+ "oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))" << endl;
786
+ indent(out) <<
787
+ "return" << endl;
788
+ indent_down();
789
+
790
+ indent(out) <<
791
+ "oprot.writeStructBegin('" << name << "')" << endl;
792
+
793
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
794
+ // Write field header
795
+ indent(out) <<
796
+ "if self." << (*f_iter)->get_name() << " != None:" << endl;
797
+ indent_up();
798
+ indent(out) <<
799
+ "oprot.writeFieldBegin(" <<
800
+ "'" << (*f_iter)->get_name() << "', " <<
801
+ type_to_enum((*f_iter)->get_type()) << ", " <<
802
+ (*f_iter)->get_key() << ")" << endl;
803
+
804
+ // Write field contents
805
+ generate_serialize_field(out, *f_iter, "self.");
806
+
807
+ // Write field closer
808
+ indent(out) <<
809
+ "oprot.writeFieldEnd()" << endl;
810
+
811
+ indent_down();
812
+ }
813
+
814
+ // Write the struct map
815
+ out <<
816
+ indent() << "oprot.writeFieldStop()" << endl <<
817
+ indent() << "oprot.writeStructEnd()" << endl;
818
+
819
+ indent_down();
820
+ out <<
821
+ endl;
822
+ }
823
+
824
+ /**
825
+ * Generates a thrift service.
826
+ *
827
+ * @param tservice The service definition
828
+ */
829
+ void t_py_generator::generate_service(t_service* tservice) {
830
+ string f_service_name = package_dir_+"/"+service_name_+".py";
831
+ f_service_.open(f_service_name.c_str());
832
+
833
+ f_service_ <<
834
+ py_autogen_comment() << endl <<
835
+ py_imports() << endl;
836
+
837
+ if (tservice->get_extends() != NULL) {
838
+ f_service_ <<
839
+ "import " << get_real_py_module(tservice->get_extends()->get_program()) <<
840
+ "." << tservice->get_extends()->get_name() << endl;
841
+ }
842
+
843
+ f_service_ <<
844
+ "from ttypes import *" << endl <<
845
+ "from thrift.Thrift import TProcessor" << endl <<
846
+ render_fastbinary_includes() << endl;
847
+
848
+ if (gen_twisted_) {
849
+ f_service_ <<
850
+ "from zope.interface import Interface, implements" << endl <<
851
+ "from twisted.internet import defer" << endl <<
852
+ "from thrift.transport import TTwisted" << endl;
853
+ }
854
+
855
+ f_service_ << endl;
856
+
857
+ // Generate the three main parts of the service (well, two for now in PHP)
858
+ generate_service_interface(tservice);
859
+ generate_service_client(tservice);
860
+ generate_service_server(tservice);
861
+ generate_service_helpers(tservice);
862
+ generate_service_remote(tservice);
863
+
864
+ // Close service file
865
+ f_service_ << endl;
866
+ f_service_.close();
867
+ }
868
+
869
+ /**
870
+ * Generates helper functions for a service.
871
+ *
872
+ * @param tservice The service to generate a header definition for
873
+ */
874
+ void t_py_generator::generate_service_helpers(t_service* tservice) {
875
+ vector<t_function*> functions = tservice->get_functions();
876
+ vector<t_function*>::iterator f_iter;
877
+
878
+ f_service_ <<
879
+ "# HELPER FUNCTIONS AND STRUCTURES" << endl << endl;
880
+
881
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
882
+ t_struct* ts = (*f_iter)->get_arglist();
883
+ generate_py_struct_definition(f_service_, ts, false);
884
+ generate_py_function_helpers(*f_iter);
885
+ }
886
+ }
887
+
888
+ /**
889
+ * Generates a struct and helpers for a function.
890
+ *
891
+ * @param tfunction The function
892
+ */
893
+ void t_py_generator::generate_py_function_helpers(t_function* tfunction) {
894
+ if (!tfunction->is_oneway()) {
895
+ t_struct result(program_, tfunction->get_name() + "_result");
896
+ t_field success(tfunction->get_returntype(), "success", 0);
897
+ if (!tfunction->get_returntype()->is_void()) {
898
+ result.append(&success);
899
+ }
900
+
901
+ t_struct* xs = tfunction->get_xceptions();
902
+ const vector<t_field*>& fields = xs->get_members();
903
+ vector<t_field*>::const_iterator f_iter;
904
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
905
+ result.append(*f_iter);
906
+ }
907
+ generate_py_struct_definition(f_service_, &result, false, true);
908
+ }
909
+ }
910
+
911
+ /**
912
+ * Generates a service interface definition.
913
+ *
914
+ * @param tservice The service to generate a header definition for
915
+ */
916
+ void t_py_generator::generate_service_interface(t_service* tservice) {
917
+ string extends = "";
918
+ string extends_if = "";
919
+ if (tservice->get_extends() != NULL) {
920
+ extends = type_name(tservice->get_extends());
921
+ extends_if = "(" + extends + ".Iface)";
922
+ } else {
923
+ if (gen_twisted_) {
924
+ extends_if = "(Interface)";
925
+ }
926
+ }
927
+
928
+ f_service_ <<
929
+ "class Iface" << extends_if << ":" << endl;
930
+ indent_up();
931
+ generate_python_docstring(f_service_, tservice);
932
+ vector<t_function*> functions = tservice->get_functions();
933
+ if (functions.empty()) {
934
+ f_service_ <<
935
+ indent() << "pass" << endl;
936
+ } else {
937
+ vector<t_function*>::iterator f_iter;
938
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
939
+ f_service_ <<
940
+ indent() << "def " << function_signature_if(*f_iter) << ":" << endl;
941
+ indent_up();
942
+ generate_python_docstring(f_service_, (*f_iter));
943
+ f_service_ <<
944
+ indent() << "pass" << endl << endl;
945
+ indent_down();
946
+ }
947
+ }
948
+
949
+ indent_down();
950
+ f_service_ <<
951
+ endl;
952
+ }
953
+
954
+ /**
955
+ * Generates a service client definition.
956
+ *
957
+ * @param tservice The service to generate a server for.
958
+ */
959
+ void t_py_generator::generate_service_client(t_service* tservice) {
960
+ string extends = "";
961
+ string extends_client = "";
962
+ if (tservice->get_extends() != NULL) {
963
+ extends = type_name(tservice->get_extends());
964
+ if (gen_twisted_) {
965
+ extends_client = "(" + extends + ".Client)";
966
+ } else {
967
+ extends_client = extends + ".Client, ";
968
+ }
969
+ } else {
970
+ if (gen_twisted_ && gen_newstyle_) {
971
+ extends_client = "(object)";
972
+ }
973
+ }
974
+
975
+ if (gen_twisted_) {
976
+ f_service_ <<
977
+ "class Client" << extends_client << ":" << endl <<
978
+ " implements(Iface)" << endl << endl;
979
+ } else {
980
+ f_service_ <<
981
+ "class Client(" << extends_client << "Iface):" << endl;
982
+ }
983
+ indent_up();
984
+ generate_python_docstring(f_service_, tservice);
985
+
986
+ // Constructor function
987
+ if (gen_twisted_) {
988
+ f_service_ <<
989
+ indent() << "def __init__(self, transport, oprot_factory):" << endl;
990
+ } else {
991
+ f_service_ <<
992
+ indent() << "def __init__(self, iprot, oprot=None):" << endl;
993
+ }
994
+ if (extends.empty()) {
995
+ if (gen_twisted_) {
996
+ f_service_ <<
997
+ indent() << " self._transport = transport" << endl <<
998
+ indent() << " self._oprot_factory = oprot_factory" << endl <<
999
+ indent() << " self._seqid = 0" << endl <<
1000
+ indent() << " self._reqs = {}" << endl <<
1001
+ endl;
1002
+ } else {
1003
+ f_service_ <<
1004
+ indent() << " self._iprot = self._oprot = iprot" << endl <<
1005
+ indent() << " if oprot != None:" << endl <<
1006
+ indent() << " self._oprot = oprot" << endl <<
1007
+ indent() << " self._seqid = 0" << endl <<
1008
+ endl;
1009
+ }
1010
+ } else {
1011
+ if (gen_twisted_) {
1012
+ f_service_ <<
1013
+ indent() << " " << extends << ".Client.__init__(self, transport, oprot_factory)" << endl <<
1014
+ endl;
1015
+ } else {
1016
+ f_service_ <<
1017
+ indent() << " " << extends << ".Client.__init__(self, iprot, oprot)" << endl <<
1018
+ endl;
1019
+ }
1020
+ }
1021
+
1022
+ // Generate client method implementations
1023
+ vector<t_function*> functions = tservice->get_functions();
1024
+ vector<t_function*>::const_iterator f_iter;
1025
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1026
+ t_struct* arg_struct = (*f_iter)->get_arglist();
1027
+ const vector<t_field*>& fields = arg_struct->get_members();
1028
+ vector<t_field*>::const_iterator fld_iter;
1029
+ string funname = (*f_iter)->get_name();
1030
+
1031
+ // Open function
1032
+ indent(f_service_) <<
1033
+ "def " << function_signature(*f_iter) << ":" << endl;
1034
+ indent_up();
1035
+ generate_python_docstring(f_service_, (*f_iter));
1036
+ if (gen_twisted_) {
1037
+ indent(f_service_) << "self._seqid += 1" << endl;
1038
+ if (!(*f_iter)->is_oneway()) {
1039
+ indent(f_service_) <<
1040
+ "d = self._reqs[self._seqid] = defer.Deferred()" << endl;
1041
+ }
1042
+ }
1043
+
1044
+ indent(f_service_) <<
1045
+ "self.send_" << funname << "(";
1046
+
1047
+ bool first = true;
1048
+ for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
1049
+ if (first) {
1050
+ first = false;
1051
+ } else {
1052
+ f_service_ << ", ";
1053
+ }
1054
+ f_service_ << (*fld_iter)->get_name();
1055
+ }
1056
+ f_service_ << ")" << endl;
1057
+
1058
+ if (!(*f_iter)->is_oneway()) {
1059
+ f_service_ << indent();
1060
+ if (gen_twisted_) {
1061
+ f_service_ << "return d" << endl;
1062
+ } else {
1063
+ if (!(*f_iter)->get_returntype()->is_void()) {
1064
+ f_service_ << "return ";
1065
+ }
1066
+ f_service_ <<
1067
+ "self.recv_" << funname << "()" << endl;
1068
+ }
1069
+ } else {
1070
+ if (gen_twisted_) {
1071
+ f_service_ <<
1072
+ indent() << "return defer.succeed(None)" << endl;
1073
+ }
1074
+ }
1075
+ indent_down();
1076
+ f_service_ << endl;
1077
+
1078
+ indent(f_service_) <<
1079
+ "def send_" << function_signature(*f_iter) << ":" << endl;
1080
+
1081
+ indent_up();
1082
+
1083
+ std::string argsname = (*f_iter)->get_name() + "_args";
1084
+
1085
+ // Serialize the request header
1086
+ if (gen_twisted_) {
1087
+ f_service_ <<
1088
+ indent() << "oprot = self._oprot_factory.getProtocol(self._transport)" << endl <<
1089
+ indent() <<
1090
+ "oprot.writeMessageBegin('" << (*f_iter)->get_name() << "', TMessageType.CALL, self._seqid)"
1091
+ << endl;
1092
+ } else {
1093
+ f_service_ <<
1094
+ indent() << "self._oprot.writeMessageBegin('" << (*f_iter)->get_name() << "', TMessageType.CALL, self._seqid)" << endl;
1095
+ }
1096
+
1097
+ f_service_ <<
1098
+ indent() << "args = " << argsname << "()" << endl;
1099
+
1100
+ for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
1101
+ f_service_ <<
1102
+ indent() << "args." << (*fld_iter)->get_name() << " = " << (*fld_iter)->get_name() << endl;
1103
+ }
1104
+
1105
+ // Write to the stream
1106
+ if (gen_twisted_) {
1107
+ f_service_ <<
1108
+ indent() << "args.write(oprot)" << endl <<
1109
+ indent() << "oprot.writeMessageEnd()" << endl <<
1110
+ indent() << "oprot.trans.flush()" << endl;
1111
+ } else {
1112
+ f_service_ <<
1113
+ indent() << "args.write(self._oprot)" << endl <<
1114
+ indent() << "self._oprot.writeMessageEnd()" << endl <<
1115
+ indent() << "self._oprot.trans.flush()" << endl;
1116
+ }
1117
+
1118
+ indent_down();
1119
+
1120
+ if (!(*f_iter)->is_oneway()) {
1121
+ std::string resultname = (*f_iter)->get_name() + "_result";
1122
+ // Open function
1123
+ f_service_ <<
1124
+ endl;
1125
+ if (gen_twisted_) {
1126
+ f_service_ <<
1127
+ indent() << "def recv_" << (*f_iter)->get_name() <<
1128
+ "(self, iprot, mtype, rseqid):" << endl;
1129
+ } else {
1130
+ t_struct noargs(program_);
1131
+ t_function recv_function((*f_iter)->get_returntype(),
1132
+ string("recv_") + (*f_iter)->get_name(),
1133
+ &noargs);
1134
+ f_service_ <<
1135
+ indent() << "def " << function_signature(&recv_function) << ":" << endl;
1136
+ }
1137
+ indent_up();
1138
+
1139
+ // TODO(mcslee): Validate message reply here, seq ids etc.
1140
+
1141
+ if (gen_twisted_) {
1142
+ f_service_ <<
1143
+ indent() << "d = self._reqs.pop(rseqid)" << endl;
1144
+ } else {
1145
+ f_service_ <<
1146
+ indent() << "(fname, mtype, rseqid) = self._iprot.readMessageBegin()" << endl;
1147
+ }
1148
+
1149
+ f_service_ <<
1150
+ indent() << "if mtype == TMessageType.EXCEPTION:" << endl <<
1151
+ indent() << " x = TApplicationException()" << endl;
1152
+
1153
+ if (gen_twisted_) {
1154
+ f_service_ <<
1155
+ indent() << " x.read(iprot)" << endl <<
1156
+ indent() << " iprot.readMessageEnd()" << endl <<
1157
+ indent() << " return d.errback(x)" << endl <<
1158
+ indent() << "result = " << resultname << "()" << endl <<
1159
+ indent() << "result.read(iprot)" << endl <<
1160
+ indent() << "iprot.readMessageEnd()" << endl;
1161
+ } else {
1162
+ f_service_ <<
1163
+ indent() << " x.read(self._iprot)" << endl <<
1164
+ indent() << " self._iprot.readMessageEnd()" << endl <<
1165
+ indent() << " raise x" << endl <<
1166
+ indent() << "result = " << resultname << "()" << endl <<
1167
+ indent() << "result.read(self._iprot)" << endl <<
1168
+ indent() << "self._iprot.readMessageEnd()" << endl;
1169
+ }
1170
+
1171
+ // Careful, only return _result if not a void function
1172
+ if (!(*f_iter)->get_returntype()->is_void()) {
1173
+ f_service_ <<
1174
+ indent() << "if result.success != None:" << endl;
1175
+ if (gen_twisted_) {
1176
+ f_service_ <<
1177
+ indent() << " return d.callback(result.success)" << endl;
1178
+ } else {
1179
+ f_service_ <<
1180
+ indent() << " return result.success" << endl;
1181
+ }
1182
+ }
1183
+
1184
+ t_struct* xs = (*f_iter)->get_xceptions();
1185
+ const std::vector<t_field*>& xceptions = xs->get_members();
1186
+ vector<t_field*>::const_iterator x_iter;
1187
+ for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
1188
+ f_service_ <<
1189
+ indent() << "if result." << (*x_iter)->get_name() << " != None:" << endl;
1190
+ if (gen_twisted_) {
1191
+ f_service_ <<
1192
+ indent() << " return d.errback(result." << (*x_iter)->get_name() << ")" << endl;
1193
+
1194
+ } else {
1195
+ f_service_ <<
1196
+ indent() << " raise result." << (*x_iter)->get_name() << "" << endl;
1197
+ }
1198
+ }
1199
+
1200
+ // Careful, only return _result if not a void function
1201
+ if ((*f_iter)->get_returntype()->is_void()) {
1202
+ if (gen_twisted_) {
1203
+ indent(f_service_) <<
1204
+ "return d.callback(None)" << endl;
1205
+ } else {
1206
+ indent(f_service_) <<
1207
+ "return" << endl;
1208
+ }
1209
+ } else {
1210
+ if (gen_twisted_) {
1211
+ f_service_ <<
1212
+ indent() << "return d.errback(TApplicationException(TApplicationException.MISSING_RESULT, \"" << (*f_iter)->get_name() << " failed: unknown result\"))" << endl;
1213
+ } else {
1214
+ f_service_ <<
1215
+ indent() << "raise TApplicationException(TApplicationException.MISSING_RESULT, \"" << (*f_iter)->get_name() << " failed: unknown result\");" << endl;
1216
+ }
1217
+ }
1218
+
1219
+ // Close function
1220
+ indent_down();
1221
+ f_service_ << endl;
1222
+ }
1223
+ }
1224
+
1225
+ indent_down();
1226
+ f_service_ <<
1227
+ endl;
1228
+ }
1229
+
1230
+ /**
1231
+ * Generates a command line tool for making remote requests
1232
+ *
1233
+ * @param tservice The service to generate a remote for.
1234
+ */
1235
+ void t_py_generator::generate_service_remote(t_service* tservice) {
1236
+ vector<t_function*> functions = tservice->get_functions();
1237
+ vector<t_function*>::iterator f_iter;
1238
+
1239
+ string f_remote_name = package_dir_+"/"+service_name_+"-remote";
1240
+ ofstream f_remote;
1241
+ f_remote.open(f_remote_name.c_str());
1242
+
1243
+ f_remote <<
1244
+ "#!/usr/bin/env python" << endl <<
1245
+ py_autogen_comment() << endl <<
1246
+ "import sys" << endl <<
1247
+ "import pprint" << endl <<
1248
+ "from urlparse import urlparse" << endl <<
1249
+ "from thrift.transport import TTransport" << endl <<
1250
+ "from thrift.transport import TSocket" << endl <<
1251
+ "from thrift.transport import THttpClient" << endl <<
1252
+ "from thrift.protocol import TBinaryProtocol" << endl <<
1253
+ endl;
1254
+
1255
+ f_remote <<
1256
+ "import " << service_name_ << endl <<
1257
+ "from ttypes import *" << endl <<
1258
+ endl;
1259
+
1260
+ f_remote <<
1261
+ "if len(sys.argv) <= 1 or sys.argv[1] == '--help':" << endl <<
1262
+ " print ''" << endl <<
1263
+ " print 'Usage: ' + sys.argv[0] + ' [-h host:port] [-u url] [-f[ramed]] function [arg1 [arg2...]]'" << endl <<
1264
+ " print ''" << endl <<
1265
+ " print 'Functions:'" << endl;
1266
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1267
+ f_remote <<
1268
+ " print ' " << (*f_iter)->get_returntype()->get_name() << " " << (*f_iter)->get_name() << "(";
1269
+ t_struct* arg_struct = (*f_iter)->get_arglist();
1270
+ const std::vector<t_field*>& args = arg_struct->get_members();
1271
+ vector<t_field*>::const_iterator a_iter;
1272
+ int num_args = args.size();
1273
+ bool first = true;
1274
+ for (int i = 0; i < num_args; ++i) {
1275
+ if (first) {
1276
+ first = false;
1277
+ } else {
1278
+ f_remote << ", ";
1279
+ }
1280
+ f_remote <<
1281
+ args[i]->get_type()->get_name() << " " << args[i]->get_name();
1282
+ }
1283
+ f_remote << ")'" << endl;
1284
+ }
1285
+ f_remote <<
1286
+ " print ''" << endl <<
1287
+ " sys.exit(0)" << endl <<
1288
+ endl;
1289
+
1290
+ f_remote <<
1291
+ "pp = pprint.PrettyPrinter(indent = 2)" << endl <<
1292
+ "host = 'localhost'" << endl <<
1293
+ "port = 9090" << endl <<
1294
+ "uri = ''" << endl <<
1295
+ "framed = False" << endl <<
1296
+ "http = False" << endl <<
1297
+ "argi = 1" << endl <<
1298
+ endl <<
1299
+ "if sys.argv[argi] == '-h':" << endl <<
1300
+ " parts = sys.argv[argi+1].split(':') " << endl <<
1301
+ " host = parts[0]" << endl <<
1302
+ " port = int(parts[1])" << endl <<
1303
+ " argi += 2" << endl <<
1304
+ endl <<
1305
+ "if sys.argv[argi] == '-u':" << endl <<
1306
+ " url = urlparse(sys.argv[argi+1])" << endl <<
1307
+ " parts = url[1].split(':') " << endl <<
1308
+ " host = parts[0]" << endl <<
1309
+ " if len(parts) > 1:" << endl <<
1310
+ " port = int(parts[1])" << endl <<
1311
+ " else:" << endl <<
1312
+ " port = 80" << endl <<
1313
+ " uri = url[2]" << endl <<
1314
+ " http = True" << endl <<
1315
+ " argi += 2" << endl <<
1316
+ endl <<
1317
+ "if sys.argv[argi] == '-f' or sys.argv[argi] == '-framed':" << endl <<
1318
+ " framed = True" << endl <<
1319
+ " argi += 1" << endl <<
1320
+ endl <<
1321
+ "cmd = sys.argv[argi]" << endl <<
1322
+ "args = sys.argv[argi+1:]" << endl <<
1323
+ endl <<
1324
+ "if http:" << endl <<
1325
+ " transport = THttpClient.THttpClient(host, port, uri)" << endl <<
1326
+ "else:" << endl <<
1327
+ " socket = TSocket.TSocket(host, port)" << endl <<
1328
+ " if framed:" << endl <<
1329
+ " transport = TTransport.TFramedTransport(socket)" << endl <<
1330
+ " else:" << endl <<
1331
+ " transport = TTransport.TBufferedTransport(socket)" << endl <<
1332
+ "protocol = TBinaryProtocol.TBinaryProtocol(transport)" << endl <<
1333
+ "client = " << service_name_ << ".Client(protocol)" << endl <<
1334
+ "transport.open()" << endl <<
1335
+ endl;
1336
+
1337
+ // Generate the dispatch methods
1338
+ bool first = true;
1339
+
1340
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1341
+ if (first) {
1342
+ first = false;
1343
+ } else {
1344
+ f_remote << "el";
1345
+ }
1346
+
1347
+ t_struct* arg_struct = (*f_iter)->get_arglist();
1348
+ const std::vector<t_field*>& args = arg_struct->get_members();
1349
+ vector<t_field*>::const_iterator a_iter;
1350
+ int num_args = args.size();
1351
+
1352
+ f_remote <<
1353
+ "if cmd == '" << (*f_iter)->get_name() << "':" << endl <<
1354
+ " if len(args) != " << num_args << ":" << endl <<
1355
+ " print '" << (*f_iter)->get_name() << " requires " << num_args << " args'" << endl <<
1356
+ " sys.exit(1)" << endl <<
1357
+ " pp.pprint(client." << (*f_iter)->get_name() << "(";
1358
+ for (int i = 0; i < num_args; ++i) {
1359
+ if (args[i]->get_type()->is_string()) {
1360
+ f_remote << "args[" << i << "],";
1361
+ } else {
1362
+ f_remote << "eval(args[" << i << "]),";
1363
+ }
1364
+ }
1365
+ f_remote << "))" << endl;
1366
+
1367
+ f_remote << endl;
1368
+ }
1369
+
1370
+ f_remote << "transport.close()" << endl;
1371
+
1372
+ // Close service file
1373
+ f_remote.close();
1374
+
1375
+ // Make file executable, love that bitwise OR action
1376
+ chmod(f_remote_name.c_str(),
1377
+ S_IRUSR
1378
+ | S_IWUSR
1379
+ | S_IXUSR
1380
+ #ifndef MINGW
1381
+ | S_IRGRP
1382
+ | S_IXGRP
1383
+ | S_IROTH
1384
+ | S_IXOTH
1385
+ #endif
1386
+ );
1387
+ }
1388
+
1389
+ /**
1390
+ * Generates a service server definition.
1391
+ *
1392
+ * @param tservice The service to generate a server for.
1393
+ */
1394
+ void t_py_generator::generate_service_server(t_service* tservice) {
1395
+ // Generate the dispatch methods
1396
+ vector<t_function*> functions = tservice->get_functions();
1397
+ vector<t_function*>::iterator f_iter;
1398
+
1399
+ string extends = "";
1400
+ string extends_processor = "";
1401
+ if (tservice->get_extends() != NULL) {
1402
+ extends = type_name(tservice->get_extends());
1403
+ extends_processor = extends + ".Processor, ";
1404
+ }
1405
+
1406
+ // Generate the header portion
1407
+ if (gen_twisted_) {
1408
+ f_service_ <<
1409
+ "class Processor(" << extends_processor << "TProcessor):" << endl <<
1410
+ " implements(Iface)" << endl << endl;
1411
+ } else {
1412
+ f_service_ <<
1413
+ "class Processor(" << extends_processor << "Iface, TProcessor):" << endl;
1414
+ }
1415
+
1416
+ indent_up();
1417
+
1418
+ indent(f_service_) <<
1419
+ "def __init__(self, handler):" << endl;
1420
+ indent_up();
1421
+ if (extends.empty()) {
1422
+ if (gen_twisted_) {
1423
+ f_service_ <<
1424
+ indent() << "self._handler = Iface(handler)" << endl;
1425
+ } else {
1426
+ f_service_ <<
1427
+ indent() << "self._handler = handler" << endl;
1428
+ }
1429
+
1430
+ f_service_ <<
1431
+ indent() << "self._processMap = {}" << endl;
1432
+ } else {
1433
+ if (gen_twisted_) {
1434
+ f_service_ <<
1435
+ indent() << extends << ".Processor.__init__(self, Iface(handler))" << endl;
1436
+ } else {
1437
+ f_service_ <<
1438
+ indent() << extends << ".Processor.__init__(self, handler)" << endl;
1439
+ }
1440
+ }
1441
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1442
+ f_service_ <<
1443
+ indent() << "self._processMap[\"" << (*f_iter)->get_name() << "\"] = Processor.process_" << (*f_iter)->get_name() << endl;
1444
+ }
1445
+ indent_down();
1446
+ f_service_ << endl;
1447
+
1448
+ // Generate the server implementation
1449
+ indent(f_service_) <<
1450
+ "def process(self, iprot, oprot):" << endl;
1451
+ indent_up();
1452
+
1453
+ f_service_ <<
1454
+ indent() << "(name, type, seqid) = iprot.readMessageBegin()" << endl;
1455
+
1456
+ // TODO(mcslee): validate message
1457
+
1458
+ // HOT: dictionary function lookup
1459
+ f_service_ <<
1460
+ indent() << "if name not in self._processMap:" << endl <<
1461
+ indent() << " iprot.skip(TType.STRUCT)" << endl <<
1462
+ indent() << " iprot.readMessageEnd()" << endl <<
1463
+ indent() << " x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown function %s' % (name))" << endl <<
1464
+ indent() << " oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid)" << endl <<
1465
+ indent() << " x.write(oprot)" << endl <<
1466
+ indent() << " oprot.writeMessageEnd()" << endl <<
1467
+ indent() << " oprot.trans.flush()" << endl;
1468
+
1469
+ if (gen_twisted_) {
1470
+ f_service_ <<
1471
+ indent() << " return defer.succeed(None)" << endl;
1472
+ } else {
1473
+ f_service_ <<
1474
+ indent() << " return" << endl;
1475
+ }
1476
+
1477
+ f_service_ <<
1478
+ indent() << "else:" << endl;
1479
+
1480
+ if (gen_twisted_) {
1481
+ f_service_ <<
1482
+ indent() << " return self._processMap[name](self, seqid, iprot, oprot)" << endl;
1483
+ } else {
1484
+ f_service_ <<
1485
+ indent() << " self._processMap[name](self, seqid, iprot, oprot)" << endl;
1486
+
1487
+ // Read end of args field, the T_STOP, and the struct close
1488
+ f_service_ <<
1489
+ indent() << "return True" << endl;
1490
+ }
1491
+
1492
+ indent_down();
1493
+ f_service_ << endl;
1494
+
1495
+ // Generate the process subfunctions
1496
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
1497
+ generate_process_function(tservice, *f_iter);
1498
+ }
1499
+
1500
+ indent_down();
1501
+ f_service_ << endl;
1502
+ }
1503
+
1504
+ /**
1505
+ * Generates a process function definition.
1506
+ *
1507
+ * @param tfunction The function to write a dispatcher for
1508
+ */
1509
+ void t_py_generator::generate_process_function(t_service* tservice,
1510
+ t_function* tfunction) {
1511
+ // Open function
1512
+ indent(f_service_) <<
1513
+ "def process_" << tfunction->get_name() <<
1514
+ "(self, seqid, iprot, oprot):" << endl;
1515
+ indent_up();
1516
+
1517
+ string argsname = tfunction->get_name() + "_args";
1518
+ string resultname = tfunction->get_name() + "_result";
1519
+
1520
+ f_service_ <<
1521
+ indent() << "args = " << argsname << "()" << endl <<
1522
+ indent() << "args.read(iprot)" << endl <<
1523
+ indent() << "iprot.readMessageEnd()" << endl;
1524
+
1525
+ t_struct* xs = tfunction->get_xceptions();
1526
+ const std::vector<t_field*>& xceptions = xs->get_members();
1527
+ vector<t_field*>::const_iterator x_iter;
1528
+
1529
+ // Declare result for non oneway function
1530
+ if (!tfunction->is_oneway()) {
1531
+ f_service_ <<
1532
+ indent() << "result = " << resultname << "()" << endl;
1533
+ }
1534
+
1535
+ if (gen_twisted_) {
1536
+ // Generate the function call
1537
+ t_struct* arg_struct = tfunction->get_arglist();
1538
+ const std::vector<t_field*>& fields = arg_struct->get_members();
1539
+ vector<t_field*>::const_iterator f_iter;
1540
+
1541
+ f_service_ <<
1542
+ indent() << "d = defer.maybeDeferred(self._handler." <<
1543
+ tfunction->get_name() << ", ";
1544
+ bool first = true;
1545
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
1546
+ if (first) {
1547
+ first = false;
1548
+ } else {
1549
+ f_service_ << ", ";
1550
+ }
1551
+ f_service_ << "args." << (*f_iter)->get_name();
1552
+ }
1553
+ f_service_ << ")" << endl;
1554
+
1555
+ // Shortcut out here for oneway functions
1556
+ if (tfunction->is_oneway()) {
1557
+ f_service_ <<
1558
+ indent() << "return d" << endl;
1559
+ indent_down();
1560
+ f_service_ << endl;
1561
+ return;
1562
+ }
1563
+
1564
+ f_service_ <<
1565
+ indent() <<
1566
+ "d.addCallback(self.write_results_success_" <<
1567
+ tfunction->get_name() << ", result, seqid, oprot)" << endl;
1568
+
1569
+ if (xceptions.size() > 0) {
1570
+ f_service_ <<
1571
+ indent() <<
1572
+ "d.addErrback(self.write_results_exception_" <<
1573
+ tfunction->get_name() << ", result, seqid, oprot)" << endl;
1574
+ }
1575
+
1576
+ f_service_ <<
1577
+ indent() << "return d" << endl;
1578
+
1579
+ indent_down();
1580
+ f_service_ << endl;
1581
+
1582
+ indent(f_service_) <<
1583
+ "def write_results_success_" << tfunction->get_name() <<
1584
+ "(self, success, result, seqid, oprot):" << endl;
1585
+ indent_up();
1586
+ f_service_ <<
1587
+ indent() << "result.success = success" << endl <<
1588
+ indent() << "oprot.writeMessageBegin(\"" << tfunction->get_name() <<
1589
+ "\", TMessageType.REPLY, seqid)" << endl <<
1590
+ indent() << "result.write(oprot)" << endl <<
1591
+ indent() << "oprot.writeMessageEnd()" << endl <<
1592
+ indent() << "oprot.trans.flush()" << endl;
1593
+ indent_down();
1594
+ f_service_ << endl;
1595
+
1596
+ // Try block for a function with exceptions
1597
+ if (!tfunction->is_oneway() && xceptions.size() > 0) {
1598
+ indent(f_service_) <<
1599
+ "def write_results_exception_" << tfunction->get_name() <<
1600
+ "(self, error, result, seqid, oprot):" << endl;
1601
+ indent_up();
1602
+ f_service_ <<
1603
+ indent() << "try:" << endl;
1604
+
1605
+ // Kinda absurd
1606
+ f_service_ <<
1607
+ indent() << " error.raiseException()" << endl;
1608
+ for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
1609
+ f_service_ <<
1610
+ indent() << "except " << type_name((*x_iter)->get_type()) << ", " << (*x_iter)->get_name() << ":" << endl;
1611
+ if (!tfunction->is_oneway()) {
1612
+ indent_up();
1613
+ f_service_ <<
1614
+ indent() << "result." << (*x_iter)->get_name() << " = " << (*x_iter)->get_name() << endl;
1615
+ indent_down();
1616
+ } else {
1617
+ f_service_ <<
1618
+ indent() << "pass" << endl;
1619
+ }
1620
+ }
1621
+ f_service_ <<
1622
+ indent() << "oprot.writeMessageBegin(\"" << tfunction->get_name() <<
1623
+ "\", TMessageType.REPLY, seqid)" << endl <<
1624
+ indent() << "result.write(oprot)" << endl <<
1625
+ indent() << "oprot.writeMessageEnd()" << endl <<
1626
+ indent() << "oprot.trans.flush()" << endl;
1627
+ indent_down();
1628
+ f_service_ << endl;
1629
+ }
1630
+ } else {
1631
+
1632
+ // Try block for a function with exceptions
1633
+ if (xceptions.size() > 0) {
1634
+ f_service_ <<
1635
+ indent() << "try:" << endl;
1636
+ indent_up();
1637
+ }
1638
+
1639
+ // Generate the function call
1640
+ t_struct* arg_struct = tfunction->get_arglist();
1641
+ const std::vector<t_field*>& fields = arg_struct->get_members();
1642
+ vector<t_field*>::const_iterator f_iter;
1643
+
1644
+ f_service_ << indent();
1645
+ if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void()) {
1646
+ f_service_ << "result.success = ";
1647
+ }
1648
+ f_service_ <<
1649
+ "self._handler." << tfunction->get_name() << "(";
1650
+ bool first = true;
1651
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
1652
+ if (first) {
1653
+ first = false;
1654
+ } else {
1655
+ f_service_ << ", ";
1656
+ }
1657
+ f_service_ << "args." << (*f_iter)->get_name();
1658
+ }
1659
+ f_service_ << ")" << endl;
1660
+
1661
+ if (!tfunction->is_oneway() && xceptions.size() > 0) {
1662
+ indent_down();
1663
+ for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
1664
+ f_service_ <<
1665
+ indent() << "except " << type_name((*x_iter)->get_type()) << ", " << (*x_iter)->get_name() << ":" << endl;
1666
+ if (!tfunction->is_oneway()) {
1667
+ indent_up();
1668
+ f_service_ <<
1669
+ indent() << "result." << (*x_iter)->get_name() << " = " << (*x_iter)->get_name() << endl;
1670
+ indent_down();
1671
+ } else {
1672
+ f_service_ <<
1673
+ indent() << "pass" << endl;
1674
+ }
1675
+ }
1676
+ }
1677
+
1678
+ // Shortcut out here for oneway functions
1679
+ if (tfunction->is_oneway()) {
1680
+ f_service_ <<
1681
+ indent() << "return" << endl;
1682
+ indent_down();
1683
+ f_service_ << endl;
1684
+ return;
1685
+ }
1686
+
1687
+ f_service_ <<
1688
+ indent() << "oprot.writeMessageBegin(\"" << tfunction->get_name() << "\", TMessageType.REPLY, seqid)" << endl <<
1689
+ indent() << "result.write(oprot)" << endl <<
1690
+ indent() << "oprot.writeMessageEnd()" << endl <<
1691
+ indent() << "oprot.trans.flush()" << endl;
1692
+
1693
+ // Close function
1694
+ indent_down();
1695
+ f_service_ << endl;
1696
+ }
1697
+ }
1698
+
1699
+ /**
1700
+ * Deserializes a field of any type.
1701
+ */
1702
+ void t_py_generator::generate_deserialize_field(ofstream &out,
1703
+ t_field* tfield,
1704
+ string prefix,
1705
+ bool inclass) {
1706
+ t_type* type = get_true_type(tfield->get_type());
1707
+
1708
+ if (type->is_void()) {
1709
+ throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " +
1710
+ prefix + tfield->get_name();
1711
+ }
1712
+
1713
+ string name = prefix + tfield->get_name();
1714
+
1715
+ if (type->is_struct() || type->is_xception()) {
1716
+ generate_deserialize_struct(out,
1717
+ (t_struct*)type,
1718
+ name);
1719
+ } else if (type->is_container()) {
1720
+ generate_deserialize_container(out, type, name);
1721
+ } else if (type->is_base_type() || type->is_enum()) {
1722
+ indent(out) <<
1723
+ name << " = iprot.";
1724
+
1725
+ if (type->is_base_type()) {
1726
+ t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
1727
+ switch (tbase) {
1728
+ case t_base_type::TYPE_VOID:
1729
+ throw "compiler error: cannot serialize void field in a struct: " +
1730
+ name;
1731
+ break;
1732
+ case t_base_type::TYPE_STRING:
1733
+ out << "readString();";
1734
+ break;
1735
+ case t_base_type::TYPE_BOOL:
1736
+ out << "readBool();";
1737
+ break;
1738
+ case t_base_type::TYPE_BYTE:
1739
+ out << "readByte();";
1740
+ break;
1741
+ case t_base_type::TYPE_I16:
1742
+ out << "readI16();";
1743
+ break;
1744
+ case t_base_type::TYPE_I32:
1745
+ out << "readI32();";
1746
+ break;
1747
+ case t_base_type::TYPE_I64:
1748
+ out << "readI64();";
1749
+ break;
1750
+ case t_base_type::TYPE_DOUBLE:
1751
+ out << "readDouble();";
1752
+ break;
1753
+ default:
1754
+ throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase);
1755
+ }
1756
+ } else if (type->is_enum()) {
1757
+ out << "readI32();";
1758
+ }
1759
+ out << endl;
1760
+
1761
+ } else {
1762
+ printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n",
1763
+ tfield->get_name().c_str(), type->get_name().c_str());
1764
+ }
1765
+ }
1766
+
1767
+ /**
1768
+ * Generates an unserializer for a struct, calling read()
1769
+ */
1770
+ void t_py_generator::generate_deserialize_struct(ofstream &out,
1771
+ t_struct* tstruct,
1772
+ string prefix) {
1773
+ out <<
1774
+ indent() << prefix << " = " << type_name(tstruct) << "()" << endl <<
1775
+ indent() << prefix << ".read(iprot)" << endl;
1776
+ }
1777
+
1778
+ /**
1779
+ * Serialize a container by writing out the header followed by
1780
+ * data and then a footer.
1781
+ */
1782
+ void t_py_generator::generate_deserialize_container(ofstream &out,
1783
+ t_type* ttype,
1784
+ string prefix) {
1785
+ string size = tmp("_size");
1786
+ string ktype = tmp("_ktype");
1787
+ string vtype = tmp("_vtype");
1788
+ string etype = tmp("_etype");
1789
+
1790
+ t_field fsize(g_type_i32, size);
1791
+ t_field fktype(g_type_byte, ktype);
1792
+ t_field fvtype(g_type_byte, vtype);
1793
+ t_field fetype(g_type_byte, etype);
1794
+
1795
+ // Declare variables, read header
1796
+ if (ttype->is_map()) {
1797
+ out <<
1798
+ indent() << prefix << " = {}" << endl <<
1799
+ indent() << "(" << ktype << ", " << vtype << ", " << size << " ) = iprot.readMapBegin() " << endl;
1800
+ } else if (ttype->is_set()) {
1801
+ out <<
1802
+ indent() << prefix << " = set()" << endl <<
1803
+ indent() << "(" << etype << ", " << size << ") = iprot.readSetBegin()" << endl;
1804
+ } else if (ttype->is_list()) {
1805
+ out <<
1806
+ indent() << prefix << " = []" << endl <<
1807
+ indent() << "(" << etype << ", " << size << ") = iprot.readListBegin()" << endl;
1808
+ }
1809
+
1810
+ // For loop iterates over elements
1811
+ string i = tmp("_i");
1812
+ indent(out) <<
1813
+ "for " << i << " in xrange(" << size << "):" << endl;
1814
+
1815
+ indent_up();
1816
+
1817
+ if (ttype->is_map()) {
1818
+ generate_deserialize_map_element(out, (t_map*)ttype, prefix);
1819
+ } else if (ttype->is_set()) {
1820
+ generate_deserialize_set_element(out, (t_set*)ttype, prefix);
1821
+ } else if (ttype->is_list()) {
1822
+ generate_deserialize_list_element(out, (t_list*)ttype, prefix);
1823
+ }
1824
+
1825
+ indent_down();
1826
+
1827
+ // Read container end
1828
+ if (ttype->is_map()) {
1829
+ indent(out) << "iprot.readMapEnd()" << endl;
1830
+ } else if (ttype->is_set()) {
1831
+ indent(out) << "iprot.readSetEnd()" << endl;
1832
+ } else if (ttype->is_list()) {
1833
+ indent(out) << "iprot.readListEnd()" << endl;
1834
+ }
1835
+ }
1836
+
1837
+
1838
+ /**
1839
+ * Generates code to deserialize a map
1840
+ */
1841
+ void t_py_generator::generate_deserialize_map_element(ofstream &out,
1842
+ t_map* tmap,
1843
+ string prefix) {
1844
+ string key = tmp("_key");
1845
+ string val = tmp("_val");
1846
+ t_field fkey(tmap->get_key_type(), key);
1847
+ t_field fval(tmap->get_val_type(), val);
1848
+
1849
+ generate_deserialize_field(out, &fkey);
1850
+ generate_deserialize_field(out, &fval);
1851
+
1852
+ indent(out) <<
1853
+ prefix << "[" << key << "] = " << val << endl;
1854
+ }
1855
+
1856
+ /**
1857
+ * Write a set element
1858
+ */
1859
+ void t_py_generator::generate_deserialize_set_element(ofstream &out,
1860
+ t_set* tset,
1861
+ string prefix) {
1862
+ string elem = tmp("_elem");
1863
+ t_field felem(tset->get_elem_type(), elem);
1864
+
1865
+ generate_deserialize_field(out, &felem);
1866
+
1867
+ indent(out) <<
1868
+ prefix << ".add(" << elem << ")" << endl;
1869
+ }
1870
+
1871
+ /**
1872
+ * Write a list element
1873
+ */
1874
+ void t_py_generator::generate_deserialize_list_element(ofstream &out,
1875
+ t_list* tlist,
1876
+ string prefix) {
1877
+ string elem = tmp("_elem");
1878
+ t_field felem(tlist->get_elem_type(), elem);
1879
+
1880
+ generate_deserialize_field(out, &felem);
1881
+
1882
+ indent(out) <<
1883
+ prefix << ".append(" << elem << ")" << endl;
1884
+ }
1885
+
1886
+
1887
+ /**
1888
+ * Serializes a field of any type.
1889
+ *
1890
+ * @param tfield The field to serialize
1891
+ * @param prefix Name to prepend to field name
1892
+ */
1893
+ void t_py_generator::generate_serialize_field(ofstream &out,
1894
+ t_field* tfield,
1895
+ string prefix) {
1896
+ t_type* type = get_true_type(tfield->get_type());
1897
+
1898
+ // Do nothing for void types
1899
+ if (type->is_void()) {
1900
+ throw "CANNOT GENERATE SERIALIZE CODE FOR void TYPE: " +
1901
+ prefix + tfield->get_name();
1902
+ }
1903
+
1904
+ if (type->is_struct() || type->is_xception()) {
1905
+ generate_serialize_struct(out,
1906
+ (t_struct*)type,
1907
+ prefix + tfield->get_name());
1908
+ } else if (type->is_container()) {
1909
+ generate_serialize_container(out,
1910
+ type,
1911
+ prefix + tfield->get_name());
1912
+ } else if (type->is_base_type() || type->is_enum()) {
1913
+
1914
+ string name = prefix + tfield->get_name();
1915
+
1916
+ indent(out) <<
1917
+ "oprot.";
1918
+
1919
+ if (type->is_base_type()) {
1920
+ t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
1921
+ switch (tbase) {
1922
+ case t_base_type::TYPE_VOID:
1923
+ throw
1924
+ "compiler error: cannot serialize void field in a struct: " + name;
1925
+ break;
1926
+ case t_base_type::TYPE_STRING:
1927
+ out << "writeString(" << name << ")";
1928
+ break;
1929
+ case t_base_type::TYPE_BOOL:
1930
+ out << "writeBool(" << name << ")";
1931
+ break;
1932
+ case t_base_type::TYPE_BYTE:
1933
+ out << "writeByte(" << name << ")";
1934
+ break;
1935
+ case t_base_type::TYPE_I16:
1936
+ out << "writeI16(" << name << ")";
1937
+ break;
1938
+ case t_base_type::TYPE_I32:
1939
+ out << "writeI32(" << name << ")";
1940
+ break;
1941
+ case t_base_type::TYPE_I64:
1942
+ out << "writeI64(" << name << ")";
1943
+ break;
1944
+ case t_base_type::TYPE_DOUBLE:
1945
+ out << "writeDouble(" << name << ")";
1946
+ break;
1947
+ default:
1948
+ throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase);
1949
+ }
1950
+ } else if (type->is_enum()) {
1951
+ out << "writeI32(" << name << ")";
1952
+ }
1953
+ out << endl;
1954
+ } else {
1955
+ printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s' TYPE '%s'\n",
1956
+ prefix.c_str(),
1957
+ tfield->get_name().c_str(),
1958
+ type->get_name().c_str());
1959
+ }
1960
+ }
1961
+
1962
+ /**
1963
+ * Serializes all the members of a struct.
1964
+ *
1965
+ * @param tstruct The struct to serialize
1966
+ * @param prefix String prefix to attach to all fields
1967
+ */
1968
+ void t_py_generator::generate_serialize_struct(ofstream &out,
1969
+ t_struct* tstruct,
1970
+ string prefix) {
1971
+ indent(out) <<
1972
+ prefix << ".write(oprot)" << endl;
1973
+ }
1974
+
1975
+ void t_py_generator::generate_serialize_container(ofstream &out,
1976
+ t_type* ttype,
1977
+ string prefix) {
1978
+ if (ttype->is_map()) {
1979
+ indent(out) <<
1980
+ "oprot.writeMapBegin(" <<
1981
+ type_to_enum(((t_map*)ttype)->get_key_type()) << ", " <<
1982
+ type_to_enum(((t_map*)ttype)->get_val_type()) << ", " <<
1983
+ "len(" << prefix << "))" << endl;
1984
+ } else if (ttype->is_set()) {
1985
+ indent(out) <<
1986
+ "oprot.writeSetBegin(" <<
1987
+ type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " <<
1988
+ "len(" << prefix << "))" << endl;
1989
+ } else if (ttype->is_list()) {
1990
+ indent(out) <<
1991
+ "oprot.writeListBegin(" <<
1992
+ type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " <<
1993
+ "len(" << prefix << "))" << endl;
1994
+ }
1995
+
1996
+ if (ttype->is_map()) {
1997
+ string kiter = tmp("kiter");
1998
+ string viter = tmp("viter");
1999
+ indent(out) <<
2000
+ "for " << kiter << "," << viter << " in " << prefix << ".items():" << endl;
2001
+ indent_up();
2002
+ generate_serialize_map_element(out, (t_map*)ttype, kiter, viter);
2003
+ indent_down();
2004
+ } else if (ttype->is_set()) {
2005
+ string iter = tmp("iter");
2006
+ indent(out) <<
2007
+ "for " << iter << " in " << prefix << ":" << endl;
2008
+ indent_up();
2009
+ generate_serialize_set_element(out, (t_set*)ttype, iter);
2010
+ indent_down();
2011
+ } else if (ttype->is_list()) {
2012
+ string iter = tmp("iter");
2013
+ indent(out) <<
2014
+ "for " << iter << " in " << prefix << ":" << endl;
2015
+ indent_up();
2016
+ generate_serialize_list_element(out, (t_list*)ttype, iter);
2017
+ indent_down();
2018
+ }
2019
+
2020
+ if (ttype->is_map()) {
2021
+ indent(out) <<
2022
+ "oprot.writeMapEnd()" << endl;
2023
+ } else if (ttype->is_set()) {
2024
+ indent(out) <<
2025
+ "oprot.writeSetEnd()" << endl;
2026
+ } else if (ttype->is_list()) {
2027
+ indent(out) <<
2028
+ "oprot.writeListEnd()" << endl;
2029
+ }
2030
+ }
2031
+
2032
+ /**
2033
+ * Serializes the members of a map.
2034
+ *
2035
+ */
2036
+ void t_py_generator::generate_serialize_map_element(ofstream &out,
2037
+ t_map* tmap,
2038
+ string kiter,
2039
+ string viter) {
2040
+ t_field kfield(tmap->get_key_type(), kiter);
2041
+ generate_serialize_field(out, &kfield, "");
2042
+
2043
+ t_field vfield(tmap->get_val_type(), viter);
2044
+ generate_serialize_field(out, &vfield, "");
2045
+ }
2046
+
2047
+ /**
2048
+ * Serializes the members of a set.
2049
+ */
2050
+ void t_py_generator::generate_serialize_set_element(ofstream &out,
2051
+ t_set* tset,
2052
+ string iter) {
2053
+ t_field efield(tset->get_elem_type(), iter);
2054
+ generate_serialize_field(out, &efield, "");
2055
+ }
2056
+
2057
+ /**
2058
+ * Serializes the members of a list.
2059
+ */
2060
+ void t_py_generator::generate_serialize_list_element(ofstream &out,
2061
+ t_list* tlist,
2062
+ string iter) {
2063
+ t_field efield(tlist->get_elem_type(), iter);
2064
+ generate_serialize_field(out, &efield, "");
2065
+ }
2066
+
2067
+ /**
2068
+ * Generates the docstring for a given struct.
2069
+ */
2070
+ void t_py_generator::generate_python_docstring(ofstream& out,
2071
+ t_struct* tstruct) {
2072
+ generate_python_docstring(out, tstruct, tstruct, "Attributes");
2073
+ }
2074
+
2075
+ /**
2076
+ * Generates the docstring for a given function.
2077
+ */
2078
+ void t_py_generator::generate_python_docstring(ofstream& out,
2079
+ t_function* tfunction) {
2080
+ generate_python_docstring(out, tfunction, tfunction->get_arglist(), "Parameters");
2081
+ }
2082
+
2083
+ /**
2084
+ * Generates the docstring for a struct or function.
2085
+ */
2086
+ void t_py_generator::generate_python_docstring(ofstream& out,
2087
+ t_doc* tdoc,
2088
+ t_struct* tstruct,
2089
+ const char* subheader) {
2090
+ bool has_doc = false;
2091
+ stringstream ss;
2092
+ if (tdoc->has_doc()) {
2093
+ has_doc = true;
2094
+ ss << tdoc->get_doc();
2095
+ }
2096
+
2097
+ const vector<t_field*>& fields = tstruct->get_members();
2098
+ if (fields.size() > 0) {
2099
+ if (has_doc) {
2100
+ ss << endl;
2101
+ }
2102
+ has_doc = true;
2103
+ ss << subheader << ":\n";
2104
+ vector<t_field*>::const_iterator p_iter;
2105
+ for (p_iter = fields.begin(); p_iter != fields.end(); ++p_iter) {
2106
+ t_field* p = *p_iter;
2107
+ ss << " - " << p->get_name();
2108
+ if (p->has_doc()) {
2109
+ ss << ": " << p->get_doc();
2110
+ } else {
2111
+ ss << endl;
2112
+ }
2113
+ }
2114
+ }
2115
+
2116
+ if (has_doc) {
2117
+ generate_docstring_comment(out,
2118
+ "\"\"\"\n",
2119
+ "", ss.str(),
2120
+ "\"\"\"\n");
2121
+ }
2122
+ }
2123
+
2124
+ /**
2125
+ * Generates the docstring for a generic object.
2126
+ */
2127
+ void t_py_generator::generate_python_docstring(ofstream& out,
2128
+ t_doc* tdoc) {
2129
+ if (tdoc->has_doc()) {
2130
+ generate_docstring_comment(out,
2131
+ "\"\"\"\n",
2132
+ "", tdoc->get_doc(),
2133
+ "\"\"\"\n");
2134
+ }
2135
+ }
2136
+
2137
+ /**
2138
+ * Declares an argument, which may include initialization as necessary.
2139
+ *
2140
+ * @param tfield The field
2141
+ */
2142
+ string t_py_generator::declare_argument(t_field* tfield) {
2143
+ std::ostringstream result;
2144
+ result << tfield->get_name() << "=";
2145
+ if (tfield->get_value() != NULL) {
2146
+ result << "thrift_spec[" <<
2147
+ tfield->get_key() << "][4]";
2148
+ } else {
2149
+ result << "None";
2150
+ }
2151
+ return result.str();
2152
+ }
2153
+
2154
+ /**
2155
+ * Renders a field default value, returns None otherwise.
2156
+ *
2157
+ * @param tfield The field
2158
+ */
2159
+ string t_py_generator::render_field_default_value(t_field* tfield) {
2160
+ t_type* type = get_true_type(tfield->get_type());
2161
+ if (tfield->get_value() != NULL) {
2162
+ return render_const_value(type, tfield->get_value());
2163
+ } else {
2164
+ return "None";
2165
+ }
2166
+ }
2167
+
2168
+ /**
2169
+ * Renders a function signature of the form 'type name(args)'
2170
+ *
2171
+ * @param tfunction Function definition
2172
+ * @return String of rendered function definition
2173
+ */
2174
+ string t_py_generator::function_signature(t_function* tfunction,
2175
+ string prefix) {
2176
+ // TODO(mcslee): Nitpicky, no ',' if argument_list is empty
2177
+ return
2178
+ prefix + tfunction->get_name() +
2179
+ "(self, " + argument_list(tfunction->get_arglist()) + ")";
2180
+ }
2181
+
2182
+ /**
2183
+ * Renders an interface function signature of the form 'type name(args)'
2184
+ *
2185
+ * @param tfunction Function definition
2186
+ * @return String of rendered function definition
2187
+ */
2188
+ string t_py_generator::function_signature_if(t_function* tfunction,
2189
+ string prefix) {
2190
+ // TODO(mcslee): Nitpicky, no ',' if argument_list is empty
2191
+ string signature = prefix + tfunction->get_name() + "(";
2192
+ if (!gen_twisted_) {
2193
+ signature += "self, ";
2194
+ }
2195
+ signature += argument_list(tfunction->get_arglist()) + ")";
2196
+ return signature;
2197
+ }
2198
+
2199
+
2200
+ /**
2201
+ * Renders a field list
2202
+ */
2203
+ string t_py_generator::argument_list(t_struct* tstruct) {
2204
+ string result = "";
2205
+
2206
+ const vector<t_field*>& fields = tstruct->get_members();
2207
+ vector<t_field*>::const_iterator f_iter;
2208
+ bool first = true;
2209
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
2210
+ if (first) {
2211
+ first = false;
2212
+ } else {
2213
+ result += ", ";
2214
+ }
2215
+ result += (*f_iter)->get_name();
2216
+ }
2217
+ return result;
2218
+ }
2219
+
2220
+ string t_py_generator::type_name(t_type* ttype) {
2221
+ t_program* program = ttype->get_program();
2222
+ if (ttype->is_service()) {
2223
+ return get_real_py_module(program) + "." + ttype->get_name();
2224
+ }
2225
+ if (program != NULL && program != program_) {
2226
+ return get_real_py_module(program) + ".ttypes." + ttype->get_name();
2227
+ }
2228
+ return ttype->get_name();
2229
+ }
2230
+
2231
+ /**
2232
+ * Converts the parse type to a Python tyoe
2233
+ */
2234
+ string t_py_generator::type_to_enum(t_type* type) {
2235
+ type = get_true_type(type);
2236
+
2237
+ if (type->is_base_type()) {
2238
+ t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
2239
+ switch (tbase) {
2240
+ case t_base_type::TYPE_VOID:
2241
+ throw "NO T_VOID CONSTRUCT";
2242
+ case t_base_type::TYPE_STRING:
2243
+ return "TType.STRING";
2244
+ case t_base_type::TYPE_BOOL:
2245
+ return "TType.BOOL";
2246
+ case t_base_type::TYPE_BYTE:
2247
+ return "TType.BYTE";
2248
+ case t_base_type::TYPE_I16:
2249
+ return "TType.I16";
2250
+ case t_base_type::TYPE_I32:
2251
+ return "TType.I32";
2252
+ case t_base_type::TYPE_I64:
2253
+ return "TType.I64";
2254
+ case t_base_type::TYPE_DOUBLE:
2255
+ return "TType.DOUBLE";
2256
+ }
2257
+ } else if (type->is_enum()) {
2258
+ return "TType.I32";
2259
+ } else if (type->is_struct() || type->is_xception()) {
2260
+ return "TType.STRUCT";
2261
+ } else if (type->is_map()) {
2262
+ return "TType.MAP";
2263
+ } else if (type->is_set()) {
2264
+ return "TType.SET";
2265
+ } else if (type->is_list()) {
2266
+ return "TType.LIST";
2267
+ }
2268
+
2269
+ throw "INVALID TYPE IN type_to_enum: " + type->get_name();
2270
+ }
2271
+
2272
+ /** See the comment inside generate_py_struct_definition for what this is. */
2273
+ string t_py_generator::type_to_spec_args(t_type* ttype) {
2274
+ while (ttype->is_typedef()) {
2275
+ ttype = ((t_typedef*)ttype)->get_type();
2276
+ }
2277
+
2278
+ if (ttype->is_base_type() || ttype->is_enum()) {
2279
+ return "None";
2280
+ } else if (ttype->is_struct() || ttype->is_xception()) {
2281
+ return "(" + type_name(ttype) + ", " + type_name(ttype) + ".thrift_spec)";
2282
+ } else if (ttype->is_map()) {
2283
+ return "(" +
2284
+ type_to_enum(((t_map*)ttype)->get_key_type()) + "," +
2285
+ type_to_spec_args(((t_map*)ttype)->get_key_type()) + "," +
2286
+ type_to_enum(((t_map*)ttype)->get_val_type()) + "," +
2287
+ type_to_spec_args(((t_map*)ttype)->get_val_type()) +
2288
+ ")";
2289
+
2290
+ } else if (ttype->is_set()) {
2291
+ return "(" +
2292
+ type_to_enum(((t_set*)ttype)->get_elem_type()) + "," +
2293
+ type_to_spec_args(((t_set*)ttype)->get_elem_type()) +
2294
+ ")";
2295
+
2296
+ } else if (ttype->is_list()) {
2297
+ return "(" +
2298
+ type_to_enum(((t_list*)ttype)->get_elem_type()) + "," +
2299
+ type_to_spec_args(((t_list*)ttype)->get_elem_type()) +
2300
+ ")";
2301
+ }
2302
+
2303
+ throw "INVALID TYPE IN type_to_spec_args: " + ttype->get_name();
2304
+ }
2305
+
2306
+
2307
+ THRIFT_REGISTER_GENERATOR(py, "Python",
2308
+ " new_style: Generate new-style classes.\n" \
2309
+ " twisted: Generate Twisted-friendly RPC services.\n"
2310
+ );