reproto 0.1.1__py3-none-any.whl → 0.1.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. .git/COMMIT_EDITMSG +30 -1
  2. .git/index +0 -0
  3. .git/logs/HEAD +1 -0
  4. .git/logs/refs/heads/iyue +1 -0
  5. .git/logs/refs/remotes/gitlab/iyue +1 -0
  6. .git/logs/refs/remotes/origin/iyue +1 -0
  7. .git/objects/03/3fab23ccc74b707a31f6f37dc5df42c100aac0 +0 -0
  8. .git/objects/07/b71df33935c14ddf99e3480c04eca4685028bc +0 -0
  9. .git/objects/0b/e20ea749c6ae1075ae98f9426e00b0a4a235af +0 -0
  10. .git/objects/13/5f50fea51c72f977f48d06a7584aba0f61e260 +0 -0
  11. .git/objects/1b/97584ebada3e93d7a2cfa4a1aae0b79c414d20 +0 -0
  12. .git/objects/1b/f0c1ad9586578e8332d061f7648dcb041ec063 +0 -0
  13. .git/objects/1e/46816d16e7c9db7575f1964403c3daa105be5c +0 -0
  14. .git/objects/27/24208ca2442e8ab9b453d0eb230fa41243b270 +0 -0
  15. .git/objects/2d/2b812ca27c477f9e1b2c2706a5eb795ffcf8eb +0 -0
  16. .git/objects/3f/b8830f516342a0ae1cb7c34b65016827cb9570 +4 -0
  17. .git/objects/41/f40c22247de377be99e30784229f3f128508a2 +0 -0
  18. .git/objects/48/cb11e75518a53be14146018214110986fade67 +0 -0
  19. .git/objects/4f/c6dc41f9c0a1a8e0eedd3ba49c43d78d0dbaba +0 -0
  20. .git/objects/59/4c23f158ccbd0a4288f9ea046d06160195afbf +0 -0
  21. .git/objects/5b/d4d87753b79e9157817f0c2e6964a731052854 +0 -0
  22. .git/objects/65/0189fe083bd711e45d463b229a72be619abad2 +0 -0
  23. .git/objects/66/663db35bfec8ef5f1a5b1c840fde1bb62a0eb8 +0 -0
  24. .git/objects/8a/0ed0ed8886fbc823e8d2258fa6d18699e94e25 +0 -0
  25. .git/objects/8d/d857b3d0ab3f5cd2e9173d532ef86e30df8eda +0 -0
  26. .git/objects/9e/23448ac58f907d9d123c32bdccedbb3d6741b5 +0 -0
  27. .git/objects/a0/d192999af7e2cbfa6a9ccd04d720a04e5a06d5 +0 -0
  28. .git/objects/a9/cc7923c34a4c97c5711d6309672f41d46c612a +0 -0
  29. .git/objects/af/c9cc15629847447063e86a82b8b56abb4fc08f +0 -0
  30. .git/objects/b1/db1c131cf32916028342c0037ce8eb57a8eb26 +0 -0
  31. .git/objects/b2/8334b94392b8af397a05ed702690fa6c9ab1ca +0 -0
  32. .git/objects/b8/7c89dcfce9e244ff5ef6a4bd394de12e8c8092 +0 -0
  33. .git/objects/d9/3bd435c8c7ad4efb83dff04d5450fabb9e3faf +0 -0
  34. .git/objects/e3/27755808d88c7ae5c06c229cf18bd0519646df +0 -0
  35. .git/objects/e5/83e7c40be934d16a1fa2e973487b395d930f42 +0 -0
  36. .git/objects/ed/1ae867d5e63195845afc58d88c38ecbdea97df +0 -0
  37. .git/objects/ef/f44e5099da27f7fb1ef14bb34902ccf4250b89 +0 -0
  38. .git/objects/f5/1be495b96272fa2e47f30071aed35ac1f0dd2c +0 -0
  39. .git/objects/fd/0bc07dc3c95e6168ab6d367d9eca139ac1e539 +0 -0
  40. .git/refs/heads/iyue +1 -1
  41. .git/refs/remotes/gitlab/iyue +1 -1
  42. .git/refs/remotes/origin/iyue +1 -1
  43. .gitignore +2 -1
  44. core/info_decoder.py +507 -6
  45. core/reconstructor.py +135 -6
  46. generation/proto_generator.py +51 -11
  47. include/google/protobuf/any.proto +162 -0
  48. include/google/protobuf/api.proto +207 -0
  49. include/google/protobuf/compiler/plugin.proto +180 -0
  50. include/google/protobuf/cpp_features.proto +67 -0
  51. include/google/protobuf/descriptor.proto +1417 -0
  52. include/google/protobuf/duration.proto +115 -0
  53. include/google/protobuf/empty.proto +51 -0
  54. include/google/protobuf/field_mask.proto +245 -0
  55. include/google/protobuf/go_features.proto +80 -0
  56. include/google/protobuf/java_features.proto +130 -0
  57. include/google/protobuf/source_context.proto +48 -0
  58. include/google/protobuf/struct.proto +95 -0
  59. include/google/protobuf/timestamp.proto +144 -0
  60. include/google/protobuf/type.proto +193 -0
  61. include/google/protobuf/wrappers.proto +157 -0
  62. parsing/java_parser.py +295 -12
  63. pyproject.toml +1 -1
  64. {reproto-0.1.1.dist-info → reproto-0.1.2.dist-info}/METADATA +1 -1
  65. {reproto-0.1.1.dist-info → reproto-0.1.2.dist-info}/RECORD +69 -20
  66. utils/builtin_proto.py +262 -0
  67. utils/type_utils.py +39 -6
  68. {reproto-0.1.1.dist-info → reproto-0.1.2.dist-info}/WHEEL +0 -0
  69. {reproto-0.1.1.dist-info → reproto-0.1.2.dist-info}/entry_points.txt +0 -0
utils/builtin_proto.py ADDED
@@ -0,0 +1,262 @@
1
+ """
2
+ Google Protobuf 内置类型管理模块
3
+ 处理内置proto文件的检测、拷贝和导入语句生成
4
+ """
5
+
6
+ import os
7
+ import shutil
8
+ from pathlib import Path
9
+ from typing import Dict, Set, Optional
10
+ from utils.logger import logger
11
+
12
+
13
+ def find_include_directory() -> Optional[Path]:
14
+ """
15
+ 查找include目录,支持开发环境和安装包环境
16
+
17
+ Returns:
18
+ include目录的路径,如果找不到则返回None
19
+ """
20
+ # 尝试多个可能的位置
21
+ possible_locations = [
22
+ # 1. 相对于当前文件的位置(开发环境)
23
+ Path(__file__).parent.parent / "include",
24
+
25
+ # 2. 相对于包安装位置(安装包环境)
26
+ Path(__file__).parent.parent.parent / "include",
27
+
28
+ # 3. 在site-packages中的位置
29
+ Path(__file__).parent / "include",
30
+
31
+ # 4. 使用pkg_resources查找(如果可用)
32
+ ]
33
+
34
+ # 尝试使用pkg_resources(推荐方式)
35
+ try:
36
+ import pkg_resources
37
+ try:
38
+ include_path = Path(pkg_resources.resource_filename('reproto', 'include'))
39
+ if include_path.exists():
40
+ possible_locations.insert(0, include_path)
41
+ except (pkg_resources.DistributionNotFound, FileNotFoundError):
42
+ pass
43
+ except ImportError:
44
+ pass
45
+
46
+ # 尝试使用importlib.resources(Python 3.9+推荐方式)
47
+ try:
48
+ import importlib.resources as resources
49
+ try:
50
+ # 对于Python 3.9+
51
+ if hasattr(resources, 'files'):
52
+ include_ref = resources.files('reproto') / 'include'
53
+ if include_ref.is_dir():
54
+ possible_locations.insert(0, Path(str(include_ref)))
55
+ except Exception:
56
+ pass
57
+ except ImportError:
58
+ pass
59
+
60
+ # 按优先级检查每个位置
61
+ for location in possible_locations:
62
+ if location.exists() and location.is_dir():
63
+ # 验证这确实是包含proto文件的include目录
64
+ wrappers_file = location / "google" / "protobuf" / "wrappers.proto"
65
+ if wrappers_file.exists():
66
+ logger.debug(f"找到include目录: {location}")
67
+ return location
68
+
69
+ logger.error("无法找到include目录")
70
+ return None
71
+
72
+
73
+ class BuiltinProtoManager:
74
+ """Google Protobuf 内置proto文件管理器"""
75
+
76
+ # 内置类型到proto文件的映射
77
+ _BUILTIN_TYPE_TO_FILE = {
78
+ # Wrapper types - 都在 wrappers.proto 中
79
+ 'google.protobuf.BoolValue': 'google/protobuf/wrappers.proto',
80
+ 'google.protobuf.Int32Value': 'google/protobuf/wrappers.proto',
81
+ 'google.protobuf.Int64Value': 'google/protobuf/wrappers.proto',
82
+ 'google.protobuf.UInt32Value': 'google/protobuf/wrappers.proto',
83
+ 'google.protobuf.UInt64Value': 'google/protobuf/wrappers.proto',
84
+ 'google.protobuf.FloatValue': 'google/protobuf/wrappers.proto',
85
+ 'google.protobuf.DoubleValue': 'google/protobuf/wrappers.proto',
86
+ 'google.protobuf.StringValue': 'google/protobuf/wrappers.proto',
87
+ 'google.protobuf.BytesValue': 'google/protobuf/wrappers.proto',
88
+
89
+ # Well-known types
90
+ 'google.protobuf.Any': 'google/protobuf/any.proto',
91
+ 'google.protobuf.Timestamp': 'google/protobuf/timestamp.proto',
92
+ 'google.protobuf.Duration': 'google/protobuf/duration.proto',
93
+ 'google.protobuf.Empty': 'google/protobuf/empty.proto',
94
+ 'google.protobuf.Struct': 'google/protobuf/struct.proto',
95
+ 'google.protobuf.Value': 'google/protobuf/struct.proto',
96
+ 'google.protobuf.ListValue': 'google/protobuf/struct.proto',
97
+ 'google.protobuf.NullValue': 'google/protobuf/struct.proto',
98
+ 'google.protobuf.FieldMask': 'google/protobuf/field_mask.proto',
99
+
100
+ # API types
101
+ 'google.protobuf.Api': 'google/protobuf/api.proto',
102
+ 'google.protobuf.Method': 'google/protobuf/api.proto',
103
+ 'google.protobuf.Mixin': 'google/protobuf/api.proto',
104
+
105
+ # Type definitions
106
+ 'google.protobuf.Type': 'google/protobuf/type.proto',
107
+ 'google.protobuf.Field': 'google/protobuf/type.proto',
108
+ 'google.protobuf.Enum': 'google/protobuf/type.proto',
109
+ 'google.protobuf.EnumValue': 'google/protobuf/type.proto',
110
+ 'google.protobuf.Option': 'google/protobuf/type.proto',
111
+ 'google.protobuf.Syntax': 'google/protobuf/type.proto',
112
+
113
+ # Source context
114
+ 'google.protobuf.SourceContext': 'google/protobuf/source_context.proto',
115
+ }
116
+
117
+ def __init__(self, include_dir: str, output_dir: str):
118
+ """
119
+ 初始化内置proto管理器
120
+
121
+ Args:
122
+ include_dir: include目录路径
123
+ output_dir: 输出目录路径
124
+ """
125
+ self.include_dir = Path(include_dir)
126
+ self.output_dir = Path(output_dir)
127
+ self._copied_files: Set[str] = set()
128
+
129
+ def is_builtin_type(self, proto_type: str) -> bool:
130
+ """
131
+ 检查是否为内置类型
132
+
133
+ Args:
134
+ proto_type: proto类型名称
135
+
136
+ Returns:
137
+ 是否为内置类型
138
+ """
139
+ return proto_type in self._BUILTIN_TYPE_TO_FILE
140
+
141
+ def get_import_path(self, proto_type: str) -> Optional[str]:
142
+ """
143
+ 获取内置类型的导入路径
144
+
145
+ Args:
146
+ proto_type: proto类型名称
147
+
148
+ Returns:
149
+ 导入路径,如果不是内置类型则返回None
150
+ """
151
+ return self._BUILTIN_TYPE_TO_FILE.get(proto_type)
152
+
153
+ def ensure_builtin_proto_file(self, proto_type: str) -> bool:
154
+ """
155
+ 确保内置proto文件存在于输出目录中
156
+
157
+ Args:
158
+ proto_type: proto类型名称
159
+
160
+ Returns:
161
+ 是否成功处理
162
+ """
163
+ if not self.is_builtin_type(proto_type):
164
+ return False
165
+
166
+ import_path = self.get_import_path(proto_type)
167
+ if not import_path:
168
+ return False
169
+
170
+ # 如果已经拷贝过,直接返回
171
+ if import_path in self._copied_files:
172
+ return True
173
+
174
+ # 源文件路径
175
+ source_file = self.include_dir / import_path
176
+ if not source_file.exists():
177
+ logger.error(f"内置proto文件不存在: {source_file}")
178
+ return False
179
+
180
+ # 目标文件路径
181
+ target_file = self.output_dir / import_path
182
+
183
+ # 创建目标目录
184
+ target_file.parent.mkdir(parents=True, exist_ok=True)
185
+
186
+ try:
187
+ # 拷贝文件
188
+ shutil.copy2(source_file, target_file)
189
+ self._copied_files.add(import_path)
190
+ logger.info(f"📄 拷贝内置proto文件: {import_path}")
191
+ return True
192
+ except Exception as e:
193
+ logger.error(f"拷贝内置proto文件失败: {source_file} -> {target_file}, 错误: {e}")
194
+ return False
195
+
196
+ def process_dependencies(self, dependencies: Set[str]) -> Dict[str, str]:
197
+ """
198
+ 处理依赖列表,返回需要的导入语句映射
199
+
200
+ Args:
201
+ dependencies: 依赖类型集合
202
+
203
+ Returns:
204
+ 类型名到导入路径的映射
205
+ """
206
+ imports = {}
207
+
208
+ for dep_type in dependencies:
209
+ if self.is_builtin_type(dep_type):
210
+ import_path = self.get_import_path(dep_type)
211
+ if import_path and self.ensure_builtin_proto_file(dep_type):
212
+ imports[dep_type] = import_path
213
+
214
+ return imports
215
+
216
+ def get_copied_files(self) -> Set[str]:
217
+ """
218
+ 获取已拷贝的文件列表
219
+
220
+ Returns:
221
+ 已拷贝文件路径的集合
222
+ """
223
+ return self._copied_files.copy()
224
+
225
+
226
+ # 全局实例(在需要时初始化)
227
+ _builtin_manager: Optional[BuiltinProtoManager] = None
228
+
229
+
230
+ def get_builtin_manager(include_dir: str = None, output_dir: str = None) -> BuiltinProtoManager:
231
+ """
232
+ 获取全局内置proto管理器实例
233
+
234
+ Args:
235
+ include_dir: include目录路径(可选,如果不提供会自动查找)
236
+ output_dir: 输出目录路径(首次调用时必需)
237
+
238
+ Returns:
239
+ BuiltinProtoManager实例
240
+ """
241
+ global _builtin_manager
242
+
243
+ if _builtin_manager is None:
244
+ if output_dir is None:
245
+ raise ValueError("首次调用get_builtin_manager时必须提供output_dir")
246
+
247
+ # 如果没有提供include_dir,自动查找
248
+ if include_dir is None:
249
+ include_path = find_include_directory()
250
+ if include_path is None:
251
+ raise ValueError("无法找到include目录,请手动指定include_dir参数")
252
+ include_dir = str(include_path)
253
+
254
+ _builtin_manager = BuiltinProtoManager(include_dir, output_dir)
255
+
256
+ return _builtin_manager
257
+
258
+
259
+ def reset_builtin_manager():
260
+ """重置全局内置proto管理器(主要用于测试)"""
261
+ global _builtin_manager
262
+ _builtin_manager = None
utils/type_utils.py CHANGED
@@ -169,9 +169,17 @@ class TypeMapper:
169
169
  """获取类型所需的导入语句"""
170
170
  imports = []
171
171
  if cls.is_well_known_type(proto_type):
172
- # 提取具体的well-known type名称
173
- type_name = proto_type.split('.')[-1].lower()
174
- imports.append(f"google/protobuf/{type_name}.proto")
172
+ # 使用内置proto管理器获取正确的导入路径
173
+ try:
174
+ from utils.builtin_proto import get_builtin_manager
175
+ builtin_manager = get_builtin_manager()
176
+ import_path = builtin_manager.get_import_path(proto_type)
177
+ if import_path:
178
+ imports.append(import_path)
179
+ except (ImportError, ValueError):
180
+ # 如果内置管理器不可用,使用旧逻辑作为后备
181
+ type_name = proto_type.split('.')[-1].lower()
182
+ imports.append(f"google/protobuf/{type_name}.proto")
175
183
  return imports
176
184
 
177
185
  @classmethod
@@ -227,7 +235,7 @@ class NamingConverter:
227
235
  @staticmethod
228
236
  def to_snake_case(camel_str: str) -> str:
229
237
  """
230
- 将CamelCase转换为snake_case
238
+ 将CamelCase转换为snake_case,同时处理$符号
231
239
 
232
240
  Args:
233
241
  camel_str: 驼峰命名字符串
@@ -238,11 +246,18 @@ class NamingConverter:
238
246
  if not camel_str:
239
247
  return camel_str
240
248
 
249
+ # 首先处理$符号:将$替换为_,处理内部类和匿名类
250
+ s0 = camel_str.replace('$', '_')
251
+
241
252
  # 处理连续大写字母:XMLParser -> XML_Parser
242
- s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', camel_str)
253
+ s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', s0)
243
254
  # 处理小写字母后跟大写字母:userId -> user_Id
244
255
  s2 = re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1)
245
- return s2.lower()
256
+
257
+ # 清理多余的下划线:将连续的下划线替换为单个下划线
258
+ s3 = re.sub('_+', '_', s2)
259
+
260
+ return s3.lower()
246
261
 
247
262
  @staticmethod
248
263
  def to_pascal_case(snake_str: str) -> str:
@@ -281,6 +296,24 @@ class NamingConverter:
281
296
 
282
297
  # 第一个单词保持小写,其余单词首字母大写
283
298
  return components[0].lower() + ''.join(word.capitalize() for word in components[1:] if word)
299
+
300
+ @staticmethod
301
+ def clean_proto_name(name: str) -> str:
302
+ """
303
+ 清理proto名称中的$符号,用于消息和枚举名称
304
+
305
+ Args:
306
+ name: 原始名称(可能包含$符号)
307
+
308
+ Returns:
309
+ 清理后的名称
310
+ """
311
+ if not name:
312
+ return name
313
+
314
+ # 将$替换为空字符串,这样Models$Device变成ModelsDevice
315
+ # 这符合proto命名规范,避免语法错误
316
+ return name.replace('$', '')
284
317
 
285
318
 
286
319
  class FieldNameProcessor: