Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #!/usr/bin/python | |
| 2 # Copyright 2016 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 """ | |
| 7 Converts a given ASCII proto into a binary resource. | |
| 8 | |
| 9 """ | |
| 10 | |
| 11 import abc | |
| 12 import optparse | |
| 13 import os | |
| 14 import re | |
| 15 import subprocess | |
| 16 import sys | |
| 17 import traceback | |
| 18 | |
| 19 class BinaryProtoGenerator: | |
| 20 | |
| 21 # If the script is run in a virtualenv | |
| 22 # (https://virtualenv.pypa.io/en/stable/), then no google.protobuf library | |
| 23 # should be brought in from site-packages. Passing -S into the interpreter in | |
| 24 # a virtualenv actually destroys the ability to import standard library | |
| 25 # functions like optparse, so this script should not be wrapped if we're in a | |
| 26 # virtualenv. | |
| 27 def _IsInVirtualEnv(self): | |
| 28 # This is the way used by pip and other software to detect virtualenv. | |
| 29 return hasattr(sys, 'real_prefix') | |
| 30 | |
| 31 def _ImportProtoModules(self, paths): | |
| 32 """Import the protobuf modules we need. |paths| is list of import paths""" | |
| 33 for path in paths: | |
| 34 # Put the path to our proto libraries in front, so that we don't use | |
| 35 # system protobuf. | |
| 36 sys.path.insert(1, path) | |
| 37 | |
| 38 import google.protobuf.text_format as text_format | |
| 39 globals()['text_format'] = text_format | |
| 40 self.ImportProtoModule() | |
| 41 | |
| 42 def _GenerateBinaryProtos(self, opts): | |
| 43 """ Read the ASCII proto and generate one or more binary protos. """ | |
| 44 # Read the ASCII | |
| 45 ifile = open(opts.infile, 'r') | |
|
Nathan Parker
2016/12/15 00:54:30
nit: Could this be one line,
ascii_pb_str = open(.
meacer
2016/12/15 18:43:36
Converted to a with block (so that the file is alw
| |
| 46 ascii_pb_str = ifile.read() | |
| 47 ifile.close() | |
| 48 | |
| 49 # Parse it into a structured PB | |
| 50 full_pb = self.EmptyProtoInstance() | |
| 51 text_format.Merge(ascii_pb_str, full_pb) | |
| 52 | |
| 53 self.ValidatePb(opts, full_pb); | |
| 54 self.ProcessPb(opts, full_pb) | |
| 55 | |
| 56 @abc.abstractmethod | |
| 57 def ImportProtoModule(self): | |
| 58 """ Import the proto module to be used by the generator. """ | |
| 59 pass | |
| 60 | |
| 61 @abc.abstractmethod | |
| 62 def EmptyProtoInstance(self): | |
| 63 """ Returns an empty proto instance to be filled by the generator.""" | |
| 64 pass | |
| 65 | |
| 66 @abc.abstractmethod | |
| 67 def ValidatePb(self, opts, pb): | |
| 68 """ Validate the basic values of the protobuf. The | |
| 69 file_type_policies_unittest.cc will also validate it by platform, | |
| 70 but this will catch errors earlier. | |
| 71 """ | |
| 72 pass | |
| 73 | |
| 74 @abc.abstractmethod | |
| 75 def ProcessPb(self, opts, pb): | |
| 76 """ Process the parsed prototobuf. """ | |
| 77 pass | |
| 78 | |
| 79 def AddCommandLineOptions(self, parser): | |
| 80 """ Allows subclasses to add any options the command line parser. """ | |
| 81 pass | |
| 82 | |
| 83 def AddExtraCommandLineArgsForVirtualEnvRun(self, opts, command): | |
| 84 """ Allows subclasses to add any extra command line arguments when running | |
| 85 this under a virtualenv.""" | |
| 86 pass | |
| 87 | |
| 88 def VerifyArgs(self, opts): | |
| 89 """ Allows subclasses to check command line parameters before running. """ | |
| 90 return True | |
| 91 | |
| 92 def Run(self): | |
| 93 parser = optparse.OptionParser() | |
| 94 # TODO(crbug.com/614082): Remove this once the bug is fixed. | |
| 95 parser.add_option('-w', '--wrap', action="store_true", default=False, | |
| 96 help='Wrap this script in another python ' | |
| 97 'execution to disable site-packages. This is a ' | |
| 98 'fix for http://crbug.com/605592') | |
| 99 | |
| 100 parser.add_option('-i', '--infile', | |
| 101 help='The ASCII proto file to read.') | |
| 102 parser.add_option('-d', '--outdir', | |
| 103 help='Directory underwhich binary file(s) will be ' + | |
| 104 'written') | |
| 105 parser.add_option('-o', '--outbasename', | |
| 106 help='Basename of the binary file to write to.') | |
| 107 parser.add_option('-p', '--path', action="append", | |
| 108 help='Repeat this as needed. Directory(s) containing ' + | |
| 109 'the your_proto_definition_pb2.py and ' + | |
| 110 'google.protobuf.text_format modules') | |
| 111 self.AddCommandLineOptions(parser) | |
| 112 | |
| 113 (opts, args) = parser.parse_args() | |
| 114 if opts.infile is None or opts.outdir is None or opts.outbasename is None: | |
| 115 parser.print_help() | |
| 116 return 1 | |
| 117 | |
| 118 if opts.wrap and not self._IsInVirtualEnv(): | |
| 119 # Run this script again with different args to the interpreter to suppress | |
| 120 # the inclusion of libraries, like google.protobuf, from site-packages, | |
| 121 # which is checked before sys.path when resolving imports. We want to | |
| 122 # specifically import the libraries injected into the sys.path in | |
| 123 # ImportProtoModules(). | |
| 124 command = [sys.executable, '-S', '-s', sys.argv[0]] | |
| 125 command += ['-i', opts.infile] | |
| 126 command += ['-d', opts.outdir] | |
| 127 command += ['-o', opts.outbasename] | |
| 128 for path in opts.path: | |
| 129 command += ['-p', path] | |
| 130 | |
| 131 self.AddExtraCommandLineArgsForVirtualEnvRun(opts, command); | |
| 132 sys.exit(subprocess.call(command)) | |
| 133 | |
| 134 self._ImportProtoModules(opts.path) | |
| 135 | |
| 136 if not self.VerifyArgs(opts): | |
| 137 print "Wrong arguments" | |
| 138 return 1 | |
| 139 | |
| 140 try: | |
| 141 self._GenerateBinaryProtos(opts) | |
| 142 except Exception as e: | |
| 143 print "ERROR: Failed to render binary version of %s:\n %s\n%s" % ( | |
| 144 opts.infile, str(e), traceback.format_exc()) | |
| 145 return 1 | |
| OLD | NEW |