xref: /aosp_15_r20/external/cronet/third_party/jni_zero/codegen/header_common.py (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1# Copyright 2024 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4"""Codegen common to .h files."""
5
6import common
7import java_types
8
9
10def class_accessors(java_classes, module_name):
11  split_arg = f'"{module_name}", ' if module_name else ''
12  sb = ['// Class Accessors.\n']
13  for java_class in java_classes:
14    if java_class in (java_types.OBJECT_CLASS, java_types.STRING_CLASS):
15      continue
16    escaped_name = common.escape_class_name(java_class.full_name_with_slashes)
17    name_with_dots = java_class.full_name_with_slashes.replace("/", ".")
18    # #ifdef needed when multple .h files are #included that common classes.
19    sb.append(f"""\
20#ifndef {escaped_name}_clazz_defined
21#define {escaped_name}_clazz_defined
22""")
23    # Uses std::atomic<> instead of "static jclass cached_class = ..." because
24    # that moves the initialize-once logic into the helper method (smaller code
25    # size).
26    sb.append(f"""\
27inline jclass {escaped_name}_clazz(JNIEnv* env) {{
28  static const char kClassName[] = "{name_with_dots}";
29  static std::atomic<jclass> cached_class;
30  return jni_zero::internal::LazyGetClass(env, kClassName, {split_arg}&cached_class);
31}}
32#endif
33
34""")
35  if len(sb) == 1:
36    return ''
37  return ''.join(sb)
38
39
40def class_accessor_expression(java_class):
41  if java_class == java_types.OBJECT_CLASS:
42    return 'jni_zero::g_object_class'
43  if java_class == java_types.STRING_CLASS:
44    return 'jni_zero::g_string_class'
45
46  escaped_name = common.escape_class_name(java_class.full_name_with_slashes)
47  return f'{escaped_name}_clazz(env)'
48
49
50def header_preamble(script_name,
51                    java_class,
52                    system_includes,
53                    user_includes,
54                    header_guard=None):
55  if header_guard is None:
56    header_guard = java_class.full_name_with_slashes.replace('/', '_') + '_JNI'
57  sb = []
58  sb.append(f"""\
59// This file was generated by
60//     {script_name}
61// For
62//     {java_class.full_name_with_dots}
63
64#ifndef {header_guard}
65#define {header_guard}
66
67""")
68  sb.extend(f'#include <{x}>\n' for x in system_includes)
69  sb.append('\n')
70  sb.extend(f'#include "{x}"\n' for x in user_includes)
71  preamble = ''.join(sb)
72
73  epilogue = f"""
74#endif  // {header_guard}
75"""
76  return preamble, epilogue
77
78
79def java_param_ref_expression(c_type, name):
80  return f'jni_zero::JavaParamRef<{c_type}>(env, {name})'
81