xref: /aosp_15_r20/external/cronet/build/protoc_java.py (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1#!/usr/bin/env python3
2# Copyright 2012 The Chromium Authors
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Generate java source files from protobuf files.
7
8This is the action script for the proto_java_library template.
9
10It performs the following steps:
111. Deletes all old sources (ensures deleted classes are not part of new jars).
122. Creates source directory.
133. Generates Java files using protoc (output into either --java-out-dir or
14   --srcjar).
154. Creates a new stamp file.
16"""
17
18
19import argparse
20import os
21import shutil
22import subprocess
23import sys
24
25import action_helpers
26import zip_helpers
27
28sys.path.append(os.path.join(os.path.dirname(__file__), 'android', 'gyp'))
29from util import build_utils
30
31
32def _HasJavaPackage(proto_lines):
33  return any(line.strip().startswith('option java_package')
34             for line in proto_lines)
35
36
37def _EnforceJavaPackage(proto_srcs):
38  for proto_path in proto_srcs:
39    with open(proto_path) as in_proto:
40      if not _HasJavaPackage(in_proto.readlines()):
41        raise Exception('Proto files for java must contain a "java_package" '
42                        'line: {}'.format(proto_path))
43
44
45def main(argv):
46  parser = argparse.ArgumentParser()
47  action_helpers.add_depfile_arg(parser)
48  parser.add_argument('--protoc', required=True, help='Path to protoc binary.')
49  parser.add_argument('--plugin', help='Path to plugin executable')
50  parser.add_argument('--proto-path',
51                      required=True,
52                      help='Path to proto directory.')
53  parser.add_argument('--java-out-dir',
54                      help='Path to output directory for java files.')
55  parser.add_argument('--srcjar', help='Path to output srcjar.')
56  parser.add_argument('--stamp', help='File to touch on success.')
57  parser.add_argument(
58      '--import-dir',
59      action='append',
60      default=[],
61      help='Extra import directory for protos, can be repeated.')
62  parser.add_argument('protos', nargs='+', help='proto source files')
63  options = parser.parse_args(argv)
64
65  if not options.java_out_dir and not options.srcjar:
66    raise Exception('One of --java-out-dir or --srcjar must be specified.')
67
68  _EnforceJavaPackage(options.protos)
69
70  with build_utils.TempDir() as temp_dir:
71    protoc_args = []
72
73    generator = 'java'
74    if options.plugin:
75      generator = 'plugin'
76      protoc_args += ['--plugin', 'protoc-gen-plugin=' + options.plugin]
77
78    protoc_args += ['--proto_path', options.proto_path]
79    for path in options.import_dir:
80      protoc_args += ['--proto_path', path]
81
82    protoc_args += ['--' + generator + '_out=lite:' + temp_dir]
83
84    # Generate Java files using protoc.
85    build_utils.CheckOutput(
86        [options.protoc] + protoc_args + options.protos,
87        # protoc generates superfluous warnings about LITE_RUNTIME deprecation
88        # even though we are using the new non-deprecated method.
89        stderr_filter=lambda output: build_utils.FilterLines(
90            output, '|'.join([r'optimize_for = LITE_RUNTIME', r'java/lite\.md'])
91        ))
92
93    if options.java_out_dir:
94      build_utils.DeleteDirectory(options.java_out_dir)
95      shutil.copytree(temp_dir, options.java_out_dir)
96    else:
97      with action_helpers.atomic_output(options.srcjar) as f:
98        zip_helpers.zip_directory(f, temp_dir)
99
100  if options.depfile:
101    assert options.srcjar
102    deps = options.protos + [options.protoc]
103    action_helpers.write_depfile(options.depfile, options.srcjar, deps)
104
105  if options.stamp:
106    build_utils.Touch(options.stamp)
107
108if __name__ == '__main__':
109  sys.exit(main(sys.argv[1:]))
110