blob: 2e14289e815a50a8b5c5ae949f9cb08d5b4c0e79 [file] [log] [blame]
#!/usr/bin/python
#
# Imports protos for PixelPerfect and fixes them to work with Android's
# proto compiler.
#
# Adapted from google3/wireless/voicesearch/tools/update_sidekick_proto.py
import os
import re
import sys
base_google3_path = "/home/build/google3/"
files = [
"net/proto2/bridge/proto/message_set.proto",
"wireless/android/play/playlog/proto/clientanalytics.proto",
"wireless/android/play/playlog/proto/personal_application_event.proto",
"wireless/android/play/playlog/proto/personal_recorder.proto",
"wireless/android/play/playlog/proto/play_games_client.proto",
"wireless/android/play/playlog/proto/play_store_client.proto"
]
# Substitutions are applied in sequence, so later substitutions see effects of
# earlier ones. This is leveraged to gracefully handle the 'default' options.
substitutions = [
# Remove the field option declaration.
('extend proto2.FieldOptions {[^}]*}', ''),
('extend proto2.EnumValueOptions {[^}]*}', ''),
# Remove options and imports that aren't applicable or supported.
('option java_api_version = 2;\n', ''),
('option py_api_version = 2;\n', ''),
('option cc_api_version = 2;\n', ''),
('option java_generate_equals_and_hash = true;\n', ''),
('option java_enable_dual_generate_mutable_api = true;\n', ''),
('import "java/com/google/apps/jspb/jspb.proto";\n', ''),
('import "logs/proto/logs_annotations/logs_annotations.proto";\n', ''),
('import "net/proto2/proto/descriptor.proto";\n', ''),
# Remove the message-level logs_proto options.
('^\s*option \(logs_proto\.\w*\) = \w*;', ''),
# Leave only default options; temporarily replace []'s with <<</>>>'s.
('\[[^]]*?default = ([^]\s,]+)[^]]*\]', '<<<\\1>>>'),
# Leave bracketed expressions in comments alone.
('(^\s*//[^\n]*)\[', '\\1{{{'),
# Zap anything between []'s.
('\[[^]]*?\]', ''),
# Restore the []'s around default options for the fields.
('<<<(.*?)>>>', '[default = \\1]'),
# Restore [ in comments.
('{{{', '['),
# Add option optimize_for = LITE_RUNTIME
('(syntax = "proto2";\n)', '\\1\noption optimize_for = LITE_RUNTIME;\n'),
# Zap unnecessary whitespace (including newlines). This will sometimes cause
# lines to become longer than 80 characters, but this is deemed an
# acceptable style violation since fixing this properly requires more time
# investment than the payoffs justify.
('([0-9])\s+;', '\\1;'),
('([0-9])\s+\[', '\\1 ['),
# Zap trailing whitespace.
(' +$', ''),
# Chomp consecutive newlines.
('\n\n\n+', '\n\n')
]
def update_proto(in_file_path, out_file_path):
in_file = file(in_file_path)
proto_source = in_file.read()
in_file.close()
for pattern, replacement in substitutions:
regex = re.compile(pattern, re.MULTILINE | re.DOTALL)
proto_source = regex.sub(replacement, proto_source)
out_file = file(out_file_path, 'w')
out_file.write(proto_source)
out_file.close()
def main(args):
script_path = os.path.realpath(sys.argv[0])
scripts_dir = os.path.dirname(script_path)
for f in files:
in_file_path = "%s%s" % (base_google3_path, f)
out_file_path = os.path.realpath(
"%s/../imported_protos/src/%s" % (scripts_dir, f))
update_proto(in_file_path, out_file_path)
print "processed %s" % f
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))