multiproto.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import os
  2. import sys
  3. NSPLIT=10
  4. def main(argv):
  5. input_dir="."
  6. output_dir="."
  7. name=sys.argv[1]
  8. if len(argv)>2:
  9. input_dir=argv[2]
  10. if len(argv)>3:
  11. output_dir=argv[3]
  12. print("name:",name)
  13. print("input_dir:",input_dir)
  14. print("output_dir:",output_dir)
  15. in_h=os.path.join(input_dir,name + ".pb.h")
  16. in_cpp=os.path.join(input_dir,name + ".pb.cc")
  17. out_h=os.path.join(output_dir,name + ".pb.main.h")
  18. out_cpp_template=os.path.join(output_dir,name + ".pb.I")
  19. with open(out_h,"w") as out_file:
  20. with open(in_h,"r") as in_file:
  21. for line in in_file:
  22. line = line.replace("inline void RegisterArenaDtor","void RegisterArenaDtor")
  23. out_file.write(line)
  24. for i in range(0,2 + NSPLIT):
  25. with open(out_cpp_template.replace("I","code" + str(i) + ".cc" if i<NSPLIT else "data.cc" if i==NSPLIT else "classes.h"),"w") as out_file:
  26. with open(in_cpp,"r") as in_file:
  27. line = line.replace("inline ","")
  28. statement_index=0
  29. current_types=set()
  30. is_data_stmt=False
  31. extern_data=False
  32. extern_code=False
  33. in_class_def=False
  34. for line in in_file:
  35. if line.startswith("#include") and name + ".pb.h" in line:
  36. out_file.write('#include "' + name + '.pb.main.h"\n')
  37. if i!=NSPLIT+1:
  38. out_file.write('#include "' + name + '.pb.classes.h"\n')
  39. continue
  40. if line.strip()=="PROTOBUF_PRAGMA_INIT_SEG":
  41. out_file.write(line)
  42. break
  43. out_file.write(line)
  44. for line in in_file:
  45. line=line.replace("inline ","")
  46. if 'Generated::' in line and line.endswith('_default_instance_._instance,\n'):
  47. line = 'reinterpret_cast<const ::_pb::Message*>(' + line.removesuffix('._instance,\n') + '),'
  48. if line.startswith("#"):
  49. out_file.write(line)
  50. continue
  51. if line.startswith("namespace") or line.startswith("PROTOBUF_NAMESPACE_OPEN"):
  52. open_namespace = True
  53. out_file.write(line)
  54. continue
  55. if (line.startswith("} // namespace") or line.startswith("PROTOBUF_NAMESPACE_CLOSE")) and open_namespace:
  56. open_namespace = False
  57. out_file.write(line)
  58. continue
  59. if in_class_def:
  60. if (i==NSPLIT+1):
  61. out_file.write(line)
  62. if line.startswith("};"):
  63. in_class_def=False
  64. continue
  65. if line.startswith("PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT"):
  66. # MOD1 MOD2 MOD3 ... type_name varibale_name;
  67. type_name=line.split(" ")[-2]
  68. if type_name in current_types:
  69. out_file.write(line)
  70. continue
  71. if line.startswith("static ") or (line.startswith("const ") and ("[]" in line or "=" in line)) or line.startswith("PROTOBUF_ATTRIBUTE_WEAK") or line.startswith("PROTOBUF_ATTRIBUTE_INIT_PRIORITY2"):
  72. is_data_stmt = True
  73. extern_data = "file_level_metadata" in line or ("descriptor_table" in line and "once" in line)
  74. extern_code = line.startswith("PROTOBUF_ATTRIBUTE_WEAK")
  75. if line.startswith("class"):
  76. in_class_def=True
  77. if i==NSPLIT+1:
  78. out_file.write(line)
  79. continue
  80. if not is_data_stmt and (statement_index % NSPLIT)==i:
  81. if line.startswith("struct"):
  82. current_types.add(line.split(" ")[1])
  83. out_file.write(line)
  84. if is_data_stmt and i==NSPLIT:
  85. if extern_data:
  86. line = line.replace("static ","")
  87. out_file.write(line)
  88. if is_data_stmt and i<NSPLIT:
  89. if extern_data or extern_code:
  90. if extern_data:
  91. line = "extern " + line.replace("static ","").replace(" = {",";")
  92. if extern_code:
  93. if not "PROTOBUF_ATTRIBUTE_WEAK" in line:
  94. continue
  95. line = "extern " + line.replace(" {",";")
  96. out_file.write(line)
  97. extern_data = False
  98. extern_code = False
  99. if line.startswith("}"):
  100. if is_data_stmt:
  101. is_data_stmt=False
  102. extern_data = False
  103. extern_code = False
  104. else:
  105. statement_index += 1
  106. if __name__ == "__main__":
  107. main(sys.argv)