| 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 with open(opts.infile, 'r') as ifile: |
| 46 ascii_pb_str = ifile.read() |
| 47 |
| 48 # Parse it into a structured PB |
| 49 full_pb = self.EmptyProtoInstance() |
| 50 text_format.Merge(ascii_pb_str, full_pb) |
| 51 |
| 52 self.ValidatePb(opts, full_pb); |
| 53 self.ProcessPb(opts, full_pb) |
| 54 |
| 55 @abc.abstractmethod |
| 56 def ImportProtoModule(self): |
| 57 """ Import the proto module to be used by the generator. """ |
| 58 pass |
| 59 |
| 60 @abc.abstractmethod |
| 61 def EmptyProtoInstance(self): |
| 62 """ Returns an empty proto instance to be filled by the generator.""" |
| 63 pass |
| 64 |
| 65 @abc.abstractmethod |
| 66 def ValidatePb(self, opts, pb): |
| 67 """ Validate the basic values of the protobuf. The |
| 68 file_type_policies_unittest.cc will also validate it by platform, |
| 69 but this will catch errors earlier. |
| 70 """ |
| 71 pass |
| 72 |
| 73 @abc.abstractmethod |
| 74 def ProcessPb(self, opts, pb): |
| 75 """ Process the parsed prototobuf. """ |
| 76 pass |
| 77 |
| 78 def AddCommandLineOptions(self, parser): |
| 79 """ Allows subclasses to add any options the command line parser. """ |
| 80 pass |
| 81 |
| 82 def AddExtraCommandLineArgsForVirtualEnvRun(self, opts, command): |
| 83 """ Allows subclasses to add any extra command line arguments when running |
| 84 this under a virtualenv.""" |
| 85 pass |
| 86 |
| 87 def VerifyArgs(self, opts): |
| 88 """ Allows subclasses to check command line parameters before running. """ |
| 89 return True |
| 90 |
| 91 def Run(self): |
| 92 parser = optparse.OptionParser() |
| 93 # TODO(crbug.com/614082): Remove this once the bug is fixed. |
| 94 parser.add_option('-w', '--wrap', action="store_true", default=False, |
| 95 help='Wrap this script in another python ' |
| 96 'execution to disable site-packages. This is a ' |
| 97 'fix for http://crbug.com/605592') |
| 98 |
| 99 parser.add_option('-i', '--infile', |
| 100 help='The ASCII proto file to read.') |
| 101 parser.add_option('-d', '--outdir', |
| 102 help='Directory underwhich binary file(s) will be ' + |
| 103 'written') |
| 104 parser.add_option('-o', '--outbasename', |
| 105 help='Basename of the binary file to write to.') |
| 106 parser.add_option('-p', '--path', action="append", |
| 107 help='Repeat this as needed. Directory(s) containing ' + |
| 108 'the your_proto_definition_pb2.py and ' + |
| 109 'google.protobuf.text_format modules') |
| 110 self.AddCommandLineOptions(parser) |
| 111 |
| 112 (opts, args) = parser.parse_args() |
| 113 if opts.infile is None or opts.outdir is None or opts.outbasename is None: |
| 114 parser.print_help() |
| 115 return 1 |
| 116 |
| 117 if opts.wrap and not self._IsInVirtualEnv(): |
| 118 # Run this script again with different args to the interpreter to suppress |
| 119 # the inclusion of libraries, like google.protobuf, from site-packages, |
| 120 # which is checked before sys.path when resolving imports. We want to |
| 121 # specifically import the libraries injected into the sys.path in |
| 122 # ImportProtoModules(). |
| 123 command = [sys.executable, '-S', '-s', sys.argv[0]] |
| 124 command += ['-i', opts.infile] |
| 125 command += ['-d', opts.outdir] |
| 126 command += ['-o', opts.outbasename] |
| 127 for path in opts.path: |
| 128 command += ['-p', path] |
| 129 |
| 130 self.AddExtraCommandLineArgsForVirtualEnvRun(opts, command); |
| 131 sys.exit(subprocess.call(command)) |
| 132 |
| 133 self._ImportProtoModules(opts.path) |
| 134 |
| 135 if not self.VerifyArgs(opts): |
| 136 print "Wrong arguments" |
| 137 return 1 |
| 138 |
| 139 try: |
| 140 self._GenerateBinaryProtos(opts) |
| 141 except Exception as e: |
| 142 print "ERROR: Failed to render binary version of %s:\n %s\n%s" % ( |
| 143 opts.infile, str(e), traceback.format_exc()) |
| 144 return 1 |
| OLD | NEW |