proxygen
gen_trace_event_constants.py
Go to the documentation of this file.
1 #!/bin/env python
2 # Copyright (c) 2015-present, Facebook, Inc.
3 # All rights reserved.
4 #
5 # This source code is licensed under the BSD-style license found in the
6 # LICENSE file in the root directory of this source tree. An additional grant
7 # of patent rights can be found in the PATENTS file in the same directory.
8 
9 
10 import os
11 import re
12 import sys
13 import optparse
14 
15 
16 def main(argv):
17  # args parser
18  parser = optparse.OptionParser()
19  parser.add_option(
20  "--install_dir",
21  dest="install_dir",
22  type="string",
23  default=None,
24  help="Absolute path to generate files",
25  )
26  parser.add_option(
27  "--fbcode_dir",
28  dest="fbcode_dir",
29  type="string",
30  default=None,
31  help="Absolute path to fbcode directory",
32  )
33  parser.add_option(
34  "--input_files",
35  dest="input_files",
36  type="string",
37  default=None,
38  help="Relative path of input file",
39  )
40  parser.add_option(
41  "--output_scope",
42  dest="output_scope",
43  type="string",
44  default=None,
45  help="namespace / package of output file",
46  )
47  parser.add_option(
48  "--output_type",
49  dest="output_type",
50  type="choice",
51  choices=["java", "cpp"],
52  default=None,
53  help="File type to generate",
54  )
55  parser.add_option(
56  "--header_path",
57  dest="header_path",
58  type="string",
59  default=None,
60  help="Relative path to cpp header",
61  )
62  options, _ = parser.parse_args()
63 
64  assert options.install_dir is not None, "Missing arg: --install_dir"
65  assert options.fbcode_dir is not None, "Missing arg: --fbcode_dir"
66  assert options.input_files is not None, "Missing arg: --input_files"
67  assert options.output_scope is not None, "Missing arg: --output_scope"
68  assert options.output_type is not None, "Missing arg: --output_type"
69 
70  file_names = options.input_files.split(",")
71  for file_name in file_names:
72  # strip the file extension and use the file name for class name
73  class_name = os.path.basename(file_name).split(".")[0]
74 
75  # parse items from source
76  items = []
77  with open(file_name, "r") as inf:
78  for line in inf:
79  sp = re.match(r"(.*), \"(.*)\"", line, re.I)
80  if sp:
81  items.append((sp.group(1), sp.group(2)))
82 
83  if options.output_type == "java":
84  gen_java(items, class_name, options.install_dir, options.output_scope)
85 
86  elif options.output_type == "cpp":
87  assert options.header_path is not None, "Missing arg: --header_path"
88 
89  gen_cpp_header(items, class_name, options.install_dir, options.output_scope)
91  items,
92  class_name,
93  options.install_dir,
94  options.header_path,
95  options.output_scope,
96  )
97 
98 
99 """
100 Generate java interface class
101 """
102 
103 
104 def gen_java(items, class_name, install_dir, output_scope):
105  packages = output_scope.split(".")
106  file_name = "%s.java" % class_name
107  file_path = os.path.join(*([install_dir, "src"] + packages))
108  output_file = os.path.join(file_path, file_name)
109 
110  if not os.path.exists(file_path):
111  os.makedirs(file_path)
112 
113  with open(output_file, "w+") as outf:
114  outf.write("// Copyright 2015-present Facebook. All Rights Reserved.\n")
115  outf.write("// ** AUTOGENERATED FILE. DO NOT HAND-EDIT **\n\n")
116  outf.write("package %s;\n\n" % ".".join(packages))
117  outf.write("public interface %s {\n" % class_name)
118 
119  for item in items:
120  outf.write(
121  ' public static final String %s = "%s";\n' % (item[0], item[1])
122  )
123 
124  outf.write("}\n")
125 
126 
127 """
128 Generate cpp enum class and provide convert function from / to string
129 """
130 
131 
132 def gen_cpp_header(items, class_name, install_dir, output_scope):
133  namespaces = output_scope.split("::")
134  file_name = "%s.h" % class_name
135  output_file = os.path.join(install_dir, file_name)
136 
137  with open(output_file, "w+") as outf:
138  outf.write("// Copyright 2015-present Facebook. All Rights Reserved.\n")
139  outf.write("// ** AUTOGENERATED FILE. DO NOT HAND-EDIT **\n\n")
140  outf.write("#pragma once\n\n")
141  outf.write("#include <string>\n\n")
142  for ns in namespaces:
143  outf.write("namespace %s { " % ns)
144  outf.write("\n\n")
145 
146  # generate enum class
147  outf.write("enum class %s {\n" % class_name)
148  for item in items:
149  outf.write(" %s,\n" % item[0])
150  outf.write("};\n\n")
151 
152  # enum to string convert function
153  outf.write(
154  "extern const std::string& get%sString(%s);\n" % (class_name, class_name)
155  )
156 
157  outf.write(
158  "extern %s get%sFromString(const std::string&);\n"
159  % (class_name, class_name)
160  )
161  for _ in namespaces:
162  outf.write("}")
163  outf.write("\n\n")
164 
165 
166 """
167 Generate cpp const string and implement convert function
168 """
169 
170 
171 def gen_cpp_source(items, class_name, install_dir, header_path, output_scope):
172  namespaces = output_scope.split("::")
173  file_name = "%s.cpp" % class_name
174  output_file = os.path.join(install_dir, file_name)
175 
176  with open(output_file, "w+") as outf:
177  outf.write("// Copyright 2015-present Facebook. All Rights Reserved.\n")
178  outf.write("// ** AUTOGENERATED FILE. DO NOT HAND-EDIT **\n\n")
179  outf.write('#include "%s/%s.h"\n\n' % (header_path, class_name))
180  outf.write("#include <stdexcept>\n\n")
181 
182  for ns in namespaces:
183  outf.write("namespace %s { " % ns)
184  outf.write("\n\n")
185 
186  # const string names
187  for item in items:
188  outf.write(
189  'static const std::string k%s%s = "%s";\n'
190  % (class_name, item[0], item[1])
191  )
192 
193  # generate enum to string convert function
194  outf.write(
195  "const std::string& get%sString(%s type) {\n" % (class_name, class_name)
196  )
197 
198  outf.write(' static const std::string k%sInvalidType = "";\n' % class_name)
199 
200  outf.write("\n switch (type) {\n")
201  for item in items:
202  outf.write(
203  " case %s::%s : return k%s%s;\n"
204  % (class_name, item[0], class_name, item[0])
205  )
206  outf.write(" }\n")
207  outf.write(" return k%sInvalidType;\n" % class_name)
208  outf.write("};\n\n")
209 
210  outf.write(
211  " %s get%sFromString(const std::string& str) {\n"
212  % (class_name, class_name)
213  )
214  for item in items:
215  outf.write(
216  " if (str == k%s%s) return %s::%s;\n"
217  % (class_name, item[0], class_name, item[0])
218  )
219  outf.write(
220  " throw std::invalid_argument"
221  ' ("No matching %s from string");\n' % (class_name)
222  )
223  outf.write("};\n")
224  outf.write("\n\n")
225  for _ in namespaces:
226  outf.write("}")
227  outf.write("\n\n")
228 
229 
230 if __name__ == "__main__":
231  sys.exit(main(sys.argv))
S split(const StringPiece source, char delimiter)
Definition: String.h:61
def gen_cpp_header(items, class_name, install_dir, output_scope)
def gen_java(items, class_name, install_dir, output_scope)
#define join
def gen_cpp_source(items, class_name, install_dir, header_path, output_scope)