Skip to content

Commit 4034f46

Browse files
committed
x
1 parent 3759945 commit 4034f46

6 files changed

Lines changed: 143 additions & 136 deletions

File tree

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1 @@
11
# SPDX-License-Identifier: Apache-2.0
2-
3-
from __future__ import annotations
4-
5-
__all__: list[str] = []

alt_core_api/tools/protoc_gen_arduinoif/core.py

Lines changed: 3 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33
from __future__ import annotations
44

55
import sys
6-
import types
7-
from pathlib import Path
86
from typing import Iterator, Tuple
97

108
from google.protobuf.compiler import plugin_pb2
119

1210
from .enum_renderer import EnumRenderer
11+
from .options_runtime import get_arduino_opts_pb2
1312
from .service_renderer import ServiceRenderer
1413
from .service_model_builder import ServiceModelBuilder
1514
from .request_context import RequestContext
@@ -19,89 +18,9 @@
1918
]
2019

2120

22-
def _load_arduino_opts_pb2() -> types.ModuleType:
23-
import importlib.util
24-
import os
25-
import re
26-
import subprocess
27-
import tempfile
28-
29-
def patch_runtime_guard(pb2_path: Path) -> None:
30-
text = pb2_path.read_text(encoding="utf-8")
31-
import_line = "from google.protobuf import runtime_version as _runtime_version\n"
32-
import_guard = (
33-
"try:\n"
34-
" from google.protobuf import runtime_version as _runtime_version\n"
35-
"except ImportError:\n"
36-
" _runtime_version = None\n"
37-
)
38-
if import_line in text and import_guard not in text:
39-
text = text.replace(import_line, import_guard)
40-
41-
pattern = re.compile(
42-
r"_runtime_version\.ValidateProtobufRuntimeVersion\(\n"
43-
r"(?P<body>(?:\s+.*\n)+?)"
44-
r"\)\n"
45-
)
46-
match = pattern.search(text)
47-
if match and "if _runtime_version is not None:" not in text:
48-
body = "".join(f" {line}" for line in match.group("body").splitlines(True))
49-
wrapped = (
50-
"if _runtime_version is not None:\n"
51-
" _runtime_version.ValidateProtobufRuntimeVersion(\n"
52-
f"{body}"
53-
" )\n"
54-
)
55-
text = text[: match.start()] + wrapped + text[match.end() :]
56-
57-
pb2_path.write_text(text, encoding="utf-8")
58-
59-
def generate_pb2_to_temp() -> Path:
60-
proto_dir = Path(__file__).resolve().parents[2] / "idl" / "proto"
61-
proto_file = proto_dir / "arduino_opts.proto"
62-
cache_dir = Path(tempfile.gettempdir()) / "protoc_gen_arduinoif_pb2"
63-
cache_dir.mkdir(parents=True, exist_ok=True)
64-
pb2_path = cache_dir / "arduino_opts_pb2.py"
65-
66-
should_generate = True
67-
if pb2_path.exists():
68-
should_generate = pb2_path.stat().st_mtime < proto_file.stat().st_mtime
69-
70-
if should_generate:
71-
subprocess.run(
72-
[
73-
"protoc",
74-
f"--proto_path={proto_dir}",
75-
f"--python_out={cache_dir}",
76-
str(proto_file),
77-
],
78-
check=True,
79-
)
80-
patch_runtime_guard(pb2_path)
81-
82-
return pb2_path
83-
84-
pb2_path = os.environ.get("PROTOC_GEN_ARDUINOIF_PB2")
85-
if pb2_path and Path(pb2_path).exists():
86-
source_path = Path(pb2_path)
87-
module_name = "_protoc_gen_arduinoif_arduino_opts_pb2"
88-
else:
89-
source_path = generate_pb2_to_temp()
90-
module_name = "_protoc_gen_arduinoif_arduino_opts_pb2_generated"
91-
92-
spec = importlib.util.spec_from_file_location(module_name, source_path)
93-
if spec is None or spec.loader is None:
94-
raise RuntimeError(f"failed to load arduino_opts_pb2 from '{source_path}'")
95-
module = importlib.util.module_from_spec(spec)
96-
spec.loader.exec_module(module)
97-
return module
98-
99-
10021
def _iter_generated_files(
10122
request: plugin_pb2.CodeGeneratorRequest,
102-
arduino_opts_pb2: types.ModuleType,
10323
) -> Iterator[Tuple[str, str]]:
104-
ServiceModelBuilder.configure_options_module(arduino_opts_pb2)
10524
context = RequestContext.build(request)
10625

10726
for proto_file in request.proto_file:
@@ -125,13 +44,13 @@ def _iter_generated_files(
12544

12645

12746
def main() -> int:
128-
arduino_opts_pb2 = _load_arduino_opts_pb2()
47+
get_arduino_opts_pb2()
12948
request = plugin_pb2.CodeGeneratorRequest()
13049
request.ParseFromString(sys.stdin.buffer.read())
13150
response = plugin_pb2.CodeGeneratorResponse()
13251

13352
try:
134-
for name, content in _iter_generated_files(request, arduino_opts_pb2):
53+
for name, content in _iter_generated_files(request):
13554
output = response.file.add()
13655
output.name = name
13756
output.content = content
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
from __future__ import annotations
4+
5+
import types
6+
from functools import lru_cache
7+
from pathlib import Path
8+
9+
__all__ = [
10+
"get_arduino_opts_pb2",
11+
]
12+
13+
14+
def _patch_runtime_guard(pb2_path: Path) -> None:
15+
import re
16+
17+
text = pb2_path.read_text(encoding="utf-8")
18+
import_line = "from google.protobuf import runtime_version as _runtime_version\n"
19+
import_guard = (
20+
"try:\n"
21+
" from google.protobuf import runtime_version as _runtime_version\n"
22+
"except ImportError:\n"
23+
" _runtime_version = None\n"
24+
)
25+
if import_line in text and import_guard not in text:
26+
text = text.replace(import_line, import_guard)
27+
28+
pattern = re.compile(
29+
r"_runtime_version\.ValidateProtobufRuntimeVersion\(\n"
30+
r"(?P<body>(?:\s+.*\n)+?)"
31+
r"\)\n"
32+
)
33+
match = pattern.search(text)
34+
if match and "if _runtime_version is not None:" not in text:
35+
body = "".join(f" {line}" for line in match.group("body").splitlines(True))
36+
wrapped = (
37+
"if _runtime_version is not None:\n"
38+
" _runtime_version.ValidateProtobufRuntimeVersion(\n"
39+
f"{body}"
40+
" )\n"
41+
)
42+
text = text[: match.start()] + wrapped + text[match.end() :]
43+
44+
pb2_path.write_text(text, encoding="utf-8")
45+
46+
47+
def _generate_pb2_to_temp() -> Path:
48+
import subprocess
49+
import tempfile
50+
51+
proto_dir = Path(__file__).resolve().parents[2] / "idl" / "proto"
52+
proto_file = proto_dir / "arduino_opts.proto"
53+
cache_dir = Path(tempfile.gettempdir()) / "protoc_gen_arduinoif_pb2"
54+
cache_dir.mkdir(parents=True, exist_ok=True)
55+
pb2_path = cache_dir / "arduino_opts_pb2.py"
56+
57+
should_generate = True
58+
if pb2_path.exists():
59+
should_generate = pb2_path.stat().st_mtime < proto_file.stat().st_mtime
60+
61+
if should_generate:
62+
subprocess.run(
63+
[
64+
"protoc",
65+
f"--proto_path={proto_dir}",
66+
f"--python_out={cache_dir}",
67+
str(proto_file),
68+
],
69+
check=True,
70+
)
71+
_patch_runtime_guard(pb2_path)
72+
73+
return pb2_path
74+
75+
76+
def _load_module_from_path(source_path: Path, module_name: str) -> types.ModuleType:
77+
import importlib.util
78+
79+
spec = importlib.util.spec_from_file_location(module_name, source_path)
80+
if spec is None or spec.loader is None:
81+
raise RuntimeError(f"failed to load arduino_opts_pb2 from '{source_path}'")
82+
module = importlib.util.module_from_spec(spec)
83+
spec.loader.exec_module(module)
84+
return module
85+
86+
87+
@lru_cache(maxsize=1)
88+
def get_arduino_opts_pb2() -> types.ModuleType:
89+
import os
90+
91+
pb2_path = os.environ.get("PROTOC_GEN_ARDUINOIF_PB2")
92+
if pb2_path and Path(pb2_path).exists():
93+
source_path = Path(pb2_path)
94+
module_name = "_protoc_gen_arduinoif_arduino_opts_pb2"
95+
else:
96+
source_path = _generate_pb2_to_temp()
97+
module_name = "_protoc_gen_arduinoif_arduino_opts_pb2_generated"
98+
return _load_module_from_path(source_path, module_name)

0 commit comments

Comments
 (0)