| OLD | NEW | 
|    1 #!/usr/bin/env python |    1 #!/usr/bin/env python | 
|    2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |    2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|    3 # Use of this source code is governed by a BSD-style license that can be |    3 # Use of this source code is governed by a BSD-style license that can be | 
|    4 # found in the LICENSE file. |    4 # found in the LICENSE file. | 
|    5 """Generator for C++ structs from api json files. |    5 """Generator for C++ structs from api json files. | 
|    6  |    6  | 
|    7 The purpose of this tool is to remove the need for hand-written code that |    7 The purpose of this tool is to remove the need for hand-written code that | 
|    8 converts to and from base::Value types when receiving javascript api calls. |    8 converts to and from base::Value types when receiving javascript api calls. | 
|    9 Originally written for generating code for extension apis. Reference schemas |    9 Originally written for generating code for extension apis. Reference schemas | 
|   10 are in chrome/common/extensions/api. |   10 are in chrome/common/extensions/api. | 
|   11  |   11  | 
|   12 Usage example: |   12 Usage example: | 
|   13   compiler.py --root /home/Work/src --namespace extensions windows.json |   13   compiler.py --root /home/Work/src --namespace extensions windows.json | 
|   14     tabs.json |   14     tabs.json | 
|   15   compiler.py --destdir gen --root /home/Work/src |   15   compiler.py --destdir gen --root /home/Work/src | 
|   16     --namespace extensions windows.json tabs.json |   16     --namespace extensions windows.json tabs.json | 
|   17 """ |   17 """ | 
|   18  |   18  | 
|   19 import cc_generator |   19 import cc_generator | 
|   20 import cpp_type_generator |   20 import cpp_type_generator | 
 |   21 import h_bundle_generator | 
|   21 import h_generator |   22 import h_generator | 
|   22 import idl_schema |   23 import idl_schema | 
|   23 import json_schema |   24 import json_schema | 
|   24 import model |   25 import model | 
|   25 import optparse |   26 import optparse | 
|   26 import os.path |   27 import os.path | 
|   27 import sys |   28 import sys | 
|   28  |   29  | 
|   29 if __name__ == '__main__': |   30 def load_schema(schema): | 
|   30   parser = optparse.OptionParser( |   31   schema_filename, schema_extension = os.path.splitext(schema) | 
|   31       description='Generates a C++ model of an API from JSON schema', |  | 
|   32       usage='usage: %prog [option]... schema') |  | 
|   33   parser.add_option('-r', '--root', default='.', |  | 
|   34       help='logical include root directory. Path to schema files from specified' |  | 
|   35       'dir will be the include path.') |  | 
|   36   parser.add_option('-d', '--destdir', |  | 
|   37       help='root directory to output generated files.') |  | 
|   38   parser.add_option('-n', '--namespace', default='generated_api_schemas', |  | 
|   39       help='C++ namespace for generated files. e.g extensions::api.') |  | 
|   40  |   32  | 
|   41   (opts, args) = parser.parse_args() |  | 
|   42   if not args: |  | 
|   43     sys.exit(parser.get_usage()) |  | 
|   44   dest_dir = opts.destdir |  | 
|   45   root_namespace = opts.namespace |  | 
|   46  |  | 
|   47   schema = os.path.normpath(args[0]) |  | 
|   48  |  | 
|   49   api_model = model.Model() |  | 
|   50  |  | 
|   51   # Actually generate for source file. |  | 
|   52   schema_filename, schema_extension = os.path.splitext(schema) |  | 
|   53   if schema_extension == '.json': |   33   if schema_extension == '.json': | 
|   54     api_defs = json_schema.Load(schema) |   34     api_defs = json_schema.Load(schema) | 
|   55   elif schema_extension == '.idl': |   35   elif schema_extension == '.idl': | 
|   56     api_defs = idl_schema.Load(schema) |   36     api_defs = idl_schema.Load(schema) | 
|   57   else: |   37   else: | 
|   58     sys.exit("Did not recognize file extension %s for schema %s" % |   38     sys.exit("Did not recognize file extension %s for schema %s" % | 
|   59              (schema_extension, schema)) |   39              (schema_extension, schema)) | 
|   60  |   40  | 
 |   41   return api_defs | 
 |   42  | 
 |   43 def handle_single_schema(filename, dest_dir, root, root_namespace): | 
 |   44   schema = os.path.normpath(filename) | 
 |   45   schema_filename, schema_extension = os.path.splitext(schema) | 
 |   46   api_defs = load_schema(schema) | 
 |   47  | 
 |   48   api_model = model.Model() | 
 |   49  | 
|   61   for target_namespace in api_defs: |   50   for target_namespace in api_defs: | 
|   62     referenced_schemas = target_namespace.get('dependencies', []) |   51     referenced_schemas = target_namespace.get('dependencies', []) | 
|   63     # Load type dependencies into the model. |   52     # Load type dependencies into the model. | 
|   64     # TODO(miket): do we need this in IDL? |   53     # TODO(miket): do we need this in IDL? | 
|   65     for referenced_schema in referenced_schemas: |   54     for referenced_schema in referenced_schemas: | 
|   66       referenced_schema_path = os.path.join( |   55       referenced_schema_path = os.path.join( | 
|   67           os.path.dirname(schema), referenced_schema + '.json') |   56           os.path.dirname(schema), referenced_schema + '.json') | 
|   68       referenced_api_defs = json_schema.Load(referenced_schema_path) |   57       referenced_api_defs = json_schema.Load(referenced_schema_path) | 
|   69  |   58  | 
|   70       for namespace in referenced_api_defs: |   59       for namespace in referenced_api_defs: | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  103           'w') as h_file: |   92           'w') as h_file: | 
|  104         h_file.write(h_code) |   93         h_file.write(h_code) | 
|  105     else: |   94     else: | 
|  106       print '%s.h' % out_file |   95       print '%s.h' % out_file | 
|  107       print |   96       print | 
|  108       print h_code |   97       print h_code | 
|  109       print |   98       print | 
|  110       print '%s.cc' % out_file |   99       print '%s.cc' % out_file | 
|  111       print |  100       print | 
|  112       print cc_code |  101       print cc_code | 
 |  102  | 
 |  103 def handle_bundle_schema(filenames, dest_dir, root, root_namespace): | 
 |  104   # Merge the source files into a single list of schemas. | 
 |  105   api_defs = [] | 
 |  106   for filename in filenames: | 
 |  107     schema = os.path.normpath(filename) | 
 |  108     schema_filename, schema_extension = os.path.splitext(schema) | 
 |  109     api_defs.extend(load_schema(schema)) | 
 |  110  | 
 |  111   api_model = model.Model() | 
 |  112   relpath = os.path.relpath(os.path.normpath(filenames[0]), root) | 
 |  113   for target_namespace in api_defs: | 
 |  114     api_model.AddNamespace(target_namespace, relpath) | 
 |  115  | 
 |  116   type_generator = cpp_type_generator.CppTypeGenerator(root_namespace) | 
 |  117   for referenced_namespace in api_model.namespaces.values(): | 
 |  118     type_generator.AddNamespace( | 
 |  119         referenced_namespace, | 
 |  120         referenced_namespace.unix_name) | 
 |  121  | 
 |  122   generator = h_bundle_generator.HBundleGenerator(api_model, type_generator) | 
 |  123   h_bundle_code = generator.Generate().Render() | 
 |  124  | 
 |  125   out_file = 'generated_api' | 
 |  126   if dest_dir: | 
 |  127     with open( | 
 |  128         os.path.join(dest_dir, 'chrome/common/extensions/api/generated_api.h'), | 
 |  129           'w') as h_file: | 
 |  130         h_file.write(h_bundle_code) | 
 |  131   else: | 
 |  132     print '%s.h' % out_file | 
 |  133     print | 
 |  134     print h_bundle_code | 
 |  135  | 
 |  136 if __name__ == '__main__': | 
 |  137   parser = optparse.OptionParser( | 
 |  138       description='Generates a C++ model of an API from JSON schema', | 
 |  139       usage='usage: %prog [option]... schema') | 
 |  140   parser.add_option('-r', '--root', default='.', | 
 |  141       help='logical include root directory. Path to schema files from specified' | 
 |  142       'dir will be the include path.') | 
 |  143   parser.add_option('-d', '--destdir', | 
 |  144       help='root directory to output generated files.') | 
 |  145   parser.add_option('-n', '--namespace', default='generated_api_schemas', | 
 |  146       help='C++ namespace for generated files. e.g extensions::api.') | 
 |  147   parser.add_option('-b', '--bundle', action="store_true", help= | 
 |  148 '''if supplied, causes compiler to generate bundle files for the given set of | 
 |  149 source files.''') | 
 |  150  | 
 |  151   (opts, args) = parser.parse_args() | 
 |  152  | 
 |  153   if not args: | 
 |  154     sys.exit(0) # This is OK as a no-op | 
 |  155   dest_dir = opts.destdir | 
 |  156   root_namespace = opts.namespace | 
 |  157  | 
 |  158   if opts.bundle: | 
 |  159     handle_bundle_schema(args, dest_dir, opts.root, root_namespace) | 
 |  160   else: | 
 |  161     handle_single_schema(args[0], dest_dir, opts.root, root_namespace) | 
| OLD | NEW |