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.
- .git/COMMIT_EDITMSG +30 -1
- .git/index +0 -0
- .git/logs/HEAD +1 -0
- .git/logs/refs/heads/iyue +1 -0
- .git/logs/refs/remotes/gitlab/iyue +1 -0
- .git/logs/refs/remotes/origin/iyue +1 -0
- .git/objects/03/3fab23ccc74b707a31f6f37dc5df42c100aac0 +0 -0
- .git/objects/07/b71df33935c14ddf99e3480c04eca4685028bc +0 -0
- .git/objects/0b/e20ea749c6ae1075ae98f9426e00b0a4a235af +0 -0
- .git/objects/13/5f50fea51c72f977f48d06a7584aba0f61e260 +0 -0
- .git/objects/1b/97584ebada3e93d7a2cfa4a1aae0b79c414d20 +0 -0
- .git/objects/1b/f0c1ad9586578e8332d061f7648dcb041ec063 +0 -0
- .git/objects/1e/46816d16e7c9db7575f1964403c3daa105be5c +0 -0
- .git/objects/27/24208ca2442e8ab9b453d0eb230fa41243b270 +0 -0
- .git/objects/2d/2b812ca27c477f9e1b2c2706a5eb795ffcf8eb +0 -0
- .git/objects/3f/b8830f516342a0ae1cb7c34b65016827cb9570 +4 -0
- .git/objects/41/f40c22247de377be99e30784229f3f128508a2 +0 -0
- .git/objects/48/cb11e75518a53be14146018214110986fade67 +0 -0
- .git/objects/4f/c6dc41f9c0a1a8e0eedd3ba49c43d78d0dbaba +0 -0
- .git/objects/59/4c23f158ccbd0a4288f9ea046d06160195afbf +0 -0
- .git/objects/5b/d4d87753b79e9157817f0c2e6964a731052854 +0 -0
- .git/objects/65/0189fe083bd711e45d463b229a72be619abad2 +0 -0
- .git/objects/66/663db35bfec8ef5f1a5b1c840fde1bb62a0eb8 +0 -0
- .git/objects/8a/0ed0ed8886fbc823e8d2258fa6d18699e94e25 +0 -0
- .git/objects/8d/d857b3d0ab3f5cd2e9173d532ef86e30df8eda +0 -0
- .git/objects/9e/23448ac58f907d9d123c32bdccedbb3d6741b5 +0 -0
- .git/objects/a0/d192999af7e2cbfa6a9ccd04d720a04e5a06d5 +0 -0
- .git/objects/a9/cc7923c34a4c97c5711d6309672f41d46c612a +0 -0
- .git/objects/af/c9cc15629847447063e86a82b8b56abb4fc08f +0 -0
- .git/objects/b1/db1c131cf32916028342c0037ce8eb57a8eb26 +0 -0
- .git/objects/b2/8334b94392b8af397a05ed702690fa6c9ab1ca +0 -0
- .git/objects/b8/7c89dcfce9e244ff5ef6a4bd394de12e8c8092 +0 -0
- .git/objects/d9/3bd435c8c7ad4efb83dff04d5450fabb9e3faf +0 -0
- .git/objects/e3/27755808d88c7ae5c06c229cf18bd0519646df +0 -0
- .git/objects/e5/83e7c40be934d16a1fa2e973487b395d930f42 +0 -0
- .git/objects/ed/1ae867d5e63195845afc58d88c38ecbdea97df +0 -0
- .git/objects/ef/f44e5099da27f7fb1ef14bb34902ccf4250b89 +0 -0
- .git/objects/f5/1be495b96272fa2e47f30071aed35ac1f0dd2c +0 -0
- .git/objects/fd/0bc07dc3c95e6168ab6d367d9eca139ac1e539 +0 -0
- .git/refs/heads/iyue +1 -1
- .git/refs/remotes/gitlab/iyue +1 -1
- .git/refs/remotes/origin/iyue +1 -1
- .gitignore +2 -1
- core/info_decoder.py +507 -6
- core/reconstructor.py +135 -6
- generation/proto_generator.py +51 -11
- include/google/protobuf/any.proto +162 -0
- include/google/protobuf/api.proto +207 -0
- include/google/protobuf/compiler/plugin.proto +180 -0
- include/google/protobuf/cpp_features.proto +67 -0
- include/google/protobuf/descriptor.proto +1417 -0
- include/google/protobuf/duration.proto +115 -0
- include/google/protobuf/empty.proto +51 -0
- include/google/protobuf/field_mask.proto +245 -0
- include/google/protobuf/go_features.proto +80 -0
- include/google/protobuf/java_features.proto +130 -0
- include/google/protobuf/source_context.proto +48 -0
- include/google/protobuf/struct.proto +95 -0
- include/google/protobuf/timestamp.proto +144 -0
- include/google/protobuf/type.proto +193 -0
- include/google/protobuf/wrappers.proto +157 -0
- parsing/java_parser.py +295 -12
- pyproject.toml +1 -1
- {reproto-0.1.1.dist-info → reproto-0.1.2.dist-info}/METADATA +1 -1
- {reproto-0.1.1.dist-info → reproto-0.1.2.dist-info}/RECORD +69 -20
- utils/builtin_proto.py +262 -0
- utils/type_utils.py +39 -6
- {reproto-0.1.1.dist-info → reproto-0.1.2.dist-info}/WHEEL +0 -0
- {reproto-0.1.1.dist-info → reproto-0.1.2.dist-info}/entry_points.txt +0 -0
core/reconstructor.py
CHANGED
@@ -267,6 +267,43 @@ class JavaSourceAnalyzer:
|
|
267
267
|
|
268
268
|
return None
|
269
269
|
|
270
|
+
def _extract_constant_value(self, constant_name: str) -> Optional[int]:
|
271
|
+
"""
|
272
|
+
从Java源码中提取常量值
|
273
|
+
|
274
|
+
Args:
|
275
|
+
constant_name: 常量名(如 "SKIP_RECOVERY_FIELD_NUMBER")
|
276
|
+
|
277
|
+
Returns:
|
278
|
+
常量值,如果找不到则返回None
|
279
|
+
"""
|
280
|
+
if not self._current_class_content:
|
281
|
+
return None
|
282
|
+
|
283
|
+
# 查找常量声明模式
|
284
|
+
patterns = [
|
285
|
+
# public static final int SKIP_RECOVERY_FIELD_NUMBER = 5;
|
286
|
+
rf'public\s+static\s+final\s+int\s+{re.escape(constant_name)}\s*=\s*(\d+)\s*;',
|
287
|
+
# private static final int SKIP_RECOVERY_FIELD_NUMBER = 5;
|
288
|
+
rf'private\s+static\s+final\s+int\s+{re.escape(constant_name)}\s*=\s*(\d+)\s*;',
|
289
|
+
# static final int SKIP_RECOVERY_FIELD_NUMBER = 5;
|
290
|
+
rf'static\s+final\s+int\s+{re.escape(constant_name)}\s*=\s*(\d+)\s*;',
|
291
|
+
# final int SKIP_RECOVERY_FIELD_NUMBER = 5;
|
292
|
+
rf'final\s+int\s+{re.escape(constant_name)}\s*=\s*(\d+)\s*;',
|
293
|
+
# int SKIP_RECOVERY_FIELD_NUMBER = 5;
|
294
|
+
rf'int\s+{re.escape(constant_name)}\s*=\s*(\d+)\s*;',
|
295
|
+
]
|
296
|
+
|
297
|
+
for pattern in patterns:
|
298
|
+
matches = re.findall(pattern, self._current_class_content)
|
299
|
+
if matches:
|
300
|
+
try:
|
301
|
+
return int(matches[0])
|
302
|
+
except ValueError:
|
303
|
+
continue
|
304
|
+
|
305
|
+
return None
|
306
|
+
|
270
307
|
def _load_class_content(self, class_name: str) -> Optional[str]:
|
271
308
|
"""加载类的源码内容(使用缓存优化)"""
|
272
309
|
try:
|
@@ -321,6 +358,10 @@ class ProtoReconstructor:
|
|
321
358
|
self.java_source_analyzer = JavaSourceAnalyzer(sources_dir)
|
322
359
|
self.info_decoder.java_source_analyzer = self.java_source_analyzer
|
323
360
|
|
361
|
+
# 初始化内置proto管理器
|
362
|
+
from utils.builtin_proto import get_builtin_manager
|
363
|
+
self.builtin_manager = get_builtin_manager(output_dir=str(output_dir))
|
364
|
+
|
324
365
|
# 🚀 性能优化:移除未使用的索引系统,简化代码
|
325
366
|
# 索引系统在实际使用中被基础类型检测绕过,且构建耗时
|
326
367
|
# 改为使用直接的文件路径构造和智能包名推断
|
@@ -460,7 +501,20 @@ class ProtoReconstructor:
|
|
460
501
|
return
|
461
502
|
|
462
503
|
# 3. 尝试解析为消息类
|
463
|
-
|
504
|
+
# 特殊处理:如果是内部类且找到的是外部类文件,需要从外部类中提取内部类信息
|
505
|
+
if '$' in class_name and java_file_path.stem != class_name.split('.')[-1]:
|
506
|
+
# 这是内部类,但找到的是外部类文件
|
507
|
+
inner_class_name = class_name.split('$')[-1] # 获取内部类名
|
508
|
+
info_string, objects_array = self.java_parser.parse_inner_class_from_file(
|
509
|
+
java_file_path, inner_class_name
|
510
|
+
)
|
511
|
+
# 为内部类创建虚拟的Java文件路径,用于字段标签提取
|
512
|
+
virtual_java_file_path = java_file_path.parent / f"{java_file_path.stem}${inner_class_name}.java"
|
513
|
+
else:
|
514
|
+
# 普通类或独立的内部类文件
|
515
|
+
info_string, objects_array = self.java_parser.parse_java_file(java_file_path)
|
516
|
+
virtual_java_file_path = java_file_path
|
517
|
+
|
464
518
|
if not info_string:
|
465
519
|
error_msg = "无法从Java文件中提取protobuf信息"
|
466
520
|
self.failed_classes[class_name] = error_msg
|
@@ -469,7 +523,7 @@ class ProtoReconstructor:
|
|
469
523
|
|
470
524
|
# 4. 解码字节码为消息定义
|
471
525
|
message_def = self.info_decoder.decode_message_info(
|
472
|
-
class_name, info_string, objects_array,
|
526
|
+
class_name, info_string, objects_array, virtual_java_file_path
|
473
527
|
)
|
474
528
|
|
475
529
|
if message_def:
|
@@ -478,6 +532,16 @@ class ProtoReconstructor:
|
|
478
532
|
|
479
533
|
# 5. 发现并添加依赖类到队列
|
480
534
|
self._discover_dependencies(message_def)
|
535
|
+
|
536
|
+
# 6. 处理InfoDecoder发现的依赖类(如oneof中的类引用)
|
537
|
+
discovered_deps = self.info_decoder.get_discovered_dependencies()
|
538
|
+
for dep_class in discovered_deps:
|
539
|
+
if dep_class not in self.processed_classes and dep_class not in self.pending_classes:
|
540
|
+
self.pending_classes.append(dep_class)
|
541
|
+
self.logger.info(f" 🔗 发现oneof依赖: {dep_class}")
|
542
|
+
|
543
|
+
# 清理InfoDecoder的依赖记录,为下次解析做准备
|
544
|
+
self.info_decoder.discovered_dependencies = []
|
481
545
|
else:
|
482
546
|
error_msg = "字节码解码失败,可能不是protobuf消息类"
|
483
547
|
self.failed_classes[class_name] = error_msg
|
@@ -503,11 +567,24 @@ class ProtoReconstructor:
|
|
503
567
|
message_def: 消息定义对象
|
504
568
|
"""
|
505
569
|
dependencies = self._extract_dependencies(message_def)
|
570
|
+
builtin_count = 0
|
571
|
+
|
506
572
|
for dep in dependencies:
|
507
|
-
|
573
|
+
# 检查是否为内置类型
|
574
|
+
if self.builtin_manager.is_builtin_type(dep):
|
575
|
+
# 处理内置类型依赖
|
576
|
+
if self.builtin_manager.ensure_builtin_proto_file(dep):
|
577
|
+
self.logger.info(f" 📦 处理内置依赖: {dep}")
|
578
|
+
builtin_count += 1
|
579
|
+
else:
|
580
|
+
self.logger.error(f" ❌ 内置依赖处理失败: {dep}")
|
581
|
+
elif dep not in self.processed_classes:
|
508
582
|
self.pending_classes.append(dep)
|
509
583
|
self.logger.info(f" 🔗 发现依赖: {dep}")
|
510
584
|
|
585
|
+
if builtin_count > 0:
|
586
|
+
self.logger.info(f" 📊 处理了 {builtin_count} 个内置依赖")
|
587
|
+
|
511
588
|
# 处理枚举依赖
|
512
589
|
self.logger.info(f" 🔍 开始处理枚举依赖...")
|
513
590
|
enum_count = 0
|
@@ -930,20 +1007,46 @@ class ProtoReconstructor:
|
|
930
1007
|
if full_path.exists():
|
931
1008
|
return full_path
|
932
1009
|
|
933
|
-
# 🚀 优化2
|
1010
|
+
# 🚀 优化2:处理内部类,正确的查找顺序
|
934
1011
|
if '$' in class_name:
|
935
|
-
# 内部类处理:com.example.Models$Inner -> com/example/Models.java
|
936
1012
|
last_dot_index = class_name.rfind('.')
|
937
1013
|
if last_dot_index != -1:
|
938
1014
|
package_path = class_name[:last_dot_index].replace('.', '/')
|
939
1015
|
class_part = class_name[last_dot_index + 1:]
|
940
1016
|
|
941
|
-
#
|
1017
|
+
# 方式1:优先查找主类文件 - 内部类通常定义在主类中
|
1018
|
+
# 如:com.example.Service$InnerClass -> 在 Service$CompleteOnboardingRequest.java 中查找
|
1019
|
+
# 这里需要找到包含这个内部类的主类文件
|
1020
|
+
outer_class_prefix = class_part.split('$')[0] # Service
|
1021
|
+
|
1022
|
+
# 在同一包下查找所有以外部类名开头的文件,并检查是否包含目标内部类
|
1023
|
+
inner_class_name = class_part.split('$')[-1] # 获取内部类名,如SkipRecovery
|
1024
|
+
package_dir = self.sources_dir / package_path
|
1025
|
+
if package_dir.exists():
|
1026
|
+
for java_file in package_dir.glob(f"{outer_class_prefix}$*.java"):
|
1027
|
+
self.logger.debug(f" 📁 检查主类文件: {java_file}")
|
1028
|
+
# 检查这个文件是否包含目标内部类
|
1029
|
+
if self._file_contains_inner_class(java_file, inner_class_name):
|
1030
|
+
self.logger.debug(f" ✅ 找到包含内部类 {inner_class_name} 的文件: {java_file}")
|
1031
|
+
return java_file
|
1032
|
+
|
1033
|
+
# 方式2:查找独立的内部类文件
|
1034
|
+
# 如:com.example.Service$InnerClass -> com/example/Service$InnerClass.java
|
1035
|
+
inner_class_file_path = f"{package_path}/{class_part}.java"
|
1036
|
+
inner_class_full_path = self.sources_dir / inner_class_file_path
|
1037
|
+
|
1038
|
+
if inner_class_full_path.exists():
|
1039
|
+
self.logger.debug(f" 📁 找到独立内部类文件: {inner_class_full_path}")
|
1040
|
+
return inner_class_full_path
|
1041
|
+
|
1042
|
+
# 方式3:传统风格 - 内部类在外部类文件中(外部类本身)
|
1043
|
+
# 如:com.example.Service$InnerClass -> com/example/Service.java
|
942
1044
|
outer_class = class_part.split('$')[0]
|
943
1045
|
outer_class_file_path = f"{package_path}/{outer_class}.java"
|
944
1046
|
outer_class_full_path = self.sources_dir / outer_class_file_path
|
945
1047
|
|
946
1048
|
if outer_class_full_path.exists():
|
1049
|
+
self.logger.debug(f" 📁 找到外部类文件: {outer_class_full_path}")
|
947
1050
|
return outer_class_full_path
|
948
1051
|
|
949
1052
|
# 🚀 优化3:简化文件查找逻辑,移除索引依赖
|
@@ -970,6 +1073,32 @@ class ProtoReconstructor:
|
|
970
1073
|
|
971
1074
|
return None
|
972
1075
|
|
1076
|
+
def _file_contains_inner_class(self, java_file_path: Path, inner_class_name: str) -> bool:
|
1077
|
+
"""
|
1078
|
+
检查Java文件是否包含指定的内部类定义
|
1079
|
+
|
1080
|
+
Args:
|
1081
|
+
java_file_path: Java文件路径
|
1082
|
+
inner_class_name: 内部类名(如"SkipRecovery")
|
1083
|
+
|
1084
|
+
Returns:
|
1085
|
+
是否包含该内部类
|
1086
|
+
"""
|
1087
|
+
try:
|
1088
|
+
content = java_file_path.read_text(encoding='utf-8')
|
1089
|
+
# 查找内部类定义
|
1090
|
+
class_pattern = rf'public\s+static\s+final\s+class\s+{re.escape(inner_class_name)}\s+extends\s+'
|
1091
|
+
if re.search(class_pattern, content):
|
1092
|
+
return True
|
1093
|
+
|
1094
|
+
# 尝试更宽松的匹配
|
1095
|
+
class_pattern = rf'class\s+{re.escape(inner_class_name)}\s+extends\s+'
|
1096
|
+
return re.search(class_pattern, content) is not None
|
1097
|
+
|
1098
|
+
except Exception as e:
|
1099
|
+
self.logger.debug(f" ❌ 检查文件 {java_file_path} 时出错: {e}")
|
1100
|
+
return False
|
1101
|
+
|
973
1102
|
def _infer_full_class_name(self, simple_name: str, current_package: str) -> Optional[str]:
|
974
1103
|
"""
|
975
1104
|
推断简单类名的完整包名(通用算法,适用于任何应用)
|
generation/proto_generator.py
CHANGED
@@ -190,7 +190,16 @@ class ProtoGenerator:
|
|
190
190
|
Returns:
|
191
191
|
消息定义的行列表
|
192
192
|
"""
|
193
|
-
|
193
|
+
# 清理消息名称中的$符号
|
194
|
+
clean_name = naming_converter.clean_proto_name(message_def.name)
|
195
|
+
|
196
|
+
lines = []
|
197
|
+
|
198
|
+
# 如果是内部类、匿名类或包含$的特殊类,添加原始Java类名注释
|
199
|
+
if message_def.full_name and ('$' in message_def.full_name or 'Anonymous' in message_def.full_name):
|
200
|
+
lines.append(f'// 原始Java类: {message_def.full_name}')
|
201
|
+
|
202
|
+
lines.append(f'message {clean_name} {{')
|
194
203
|
|
195
204
|
# 生成oneof字段(oneof字段内部也按tag排序)
|
196
205
|
for oneof in message_def.oneofs:
|
@@ -214,7 +223,16 @@ class ProtoGenerator:
|
|
214
223
|
Returns:
|
215
224
|
枚举定义的行列表
|
216
225
|
"""
|
217
|
-
|
226
|
+
# 清理枚举名称中的$符号
|
227
|
+
clean_name = naming_converter.clean_proto_name(enum_def.name)
|
228
|
+
|
229
|
+
lines = []
|
230
|
+
|
231
|
+
# 如果是内部类、匿名类或包含$的特殊enum,添加原始Java类名注释
|
232
|
+
if enum_def.full_name and ('$' in enum_def.full_name or 'Anonymous' in enum_def.full_name):
|
233
|
+
lines.append(f'// 原始Java类: {enum_def.full_name}')
|
234
|
+
|
235
|
+
lines.append(f'enum {clean_name} {{')
|
218
236
|
|
219
237
|
# 生成枚举值(按value排序)
|
220
238
|
sorted_values = sorted(enum_def.values, key=lambda enum_value: enum_value.value)
|
@@ -335,6 +353,16 @@ class ProtoGenerator:
|
|
335
353
|
if field.type_name in basic_proto_types:
|
336
354
|
return None
|
337
355
|
|
356
|
+
# 检查是否为Google Protobuf内置类型
|
357
|
+
try:
|
358
|
+
from utils.builtin_proto import get_builtin_manager
|
359
|
+
builtin_manager = get_builtin_manager()
|
360
|
+
if builtin_manager.is_builtin_type(field.type_name):
|
361
|
+
return builtin_manager.get_import_path(field.type_name)
|
362
|
+
except (ImportError, ValueError):
|
363
|
+
# 如果内置管理器不可用,继续使用原有逻辑
|
364
|
+
pass
|
365
|
+
|
338
366
|
# 处理map类型:map<string, Contact> -> 提取值类型Contact
|
339
367
|
if field.type_name.startswith('map<'):
|
340
368
|
# 解析map类型:map<key_type, value_type>
|
@@ -366,6 +394,10 @@ class ProtoGenerator:
|
|
366
394
|
# 生成枚举文件的导入路径
|
367
395
|
return self._class_name_to_import_path(enum_full_name)
|
368
396
|
|
397
|
+
# 优先使用字段定义中保存的完整类名信息(用于内部类等特殊情况)
|
398
|
+
if hasattr(field, 'full_class_name') and field.full_class_name:
|
399
|
+
return self._class_name_to_import_path(field.full_class_name)
|
400
|
+
|
369
401
|
# 解析完整类名(消息类型)
|
370
402
|
full_class_name = self._resolve_full_class_name(field.type_name, current_package, all_messages)
|
371
403
|
if full_class_name:
|
@@ -418,9 +450,12 @@ class ProtoGenerator:
|
|
418
450
|
Returns:
|
419
451
|
proto导入路径
|
420
452
|
"""
|
421
|
-
# com.example.
|
453
|
+
# com.example.Service$SkipRecovery -> com/example/service_skip_recovery.proto
|
454
|
+
# 注意:这里要使用完整的类名(包含$符号)来生成文件名,与实际文件名保持一致
|
422
455
|
parts = class_name.split('.')
|
423
|
-
|
456
|
+
# 使用完整的类名部分(可能包含$)来生成proto文件名
|
457
|
+
class_part = parts[-1]
|
458
|
+
proto_name = self._to_snake_case(class_part) + '.proto'
|
424
459
|
package_path = '/'.join(parts[:-1])
|
425
460
|
return f"{package_path}/{proto_name}"
|
426
461
|
|
@@ -464,20 +499,25 @@ class ProtoGenerator:
|
|
464
499
|
if field.type_name == 'message':
|
465
500
|
return self._generate_message_type_name(field.name)
|
466
501
|
|
467
|
-
#
|
502
|
+
# 检查是否为枚举类型,如果是则使用清理后的枚举名
|
468
503
|
if all_enums:
|
469
504
|
for enum_full_name, enum_def in all_enums.items():
|
470
505
|
enum_class_name = enum_full_name.split('.')[-1] # 获取类名部分
|
471
506
|
if field.type_name == enum_class_name:
|
472
|
-
#
|
473
|
-
return enum_def.name
|
507
|
+
# 使用清理后的枚举名,去掉$符号
|
508
|
+
return naming_converter.clean_proto_name(enum_def.name)
|
474
509
|
|
475
|
-
#
|
510
|
+
# 已知的具体类型名,处理Google Protobuf类型和普通类型
|
476
511
|
if '.' in field.type_name:
|
477
|
-
#
|
478
|
-
|
512
|
+
# 如果是Google Protobuf类型,保持完整的类型名
|
513
|
+
if field.type_name.startswith('google.protobuf.'):
|
514
|
+
return field.type_name
|
515
|
+
# 其他类型提取简单类型名,并清理$符号
|
516
|
+
simple_name = field.type_name.split('.')[-1]
|
517
|
+
return naming_converter.clean_proto_name(simple_name)
|
479
518
|
else:
|
480
|
-
|
519
|
+
# 清理简单类型名中的$符号
|
520
|
+
return naming_converter.clean_proto_name(field.type_name)
|
481
521
|
|
482
522
|
def _get_basic_proto_type(self, type_name: str) -> str:
|
483
523
|
"""
|
@@ -0,0 +1,162 @@
|
|
1
|
+
// Protocol Buffers - Google's data interchange format
|
2
|
+
// Copyright 2008 Google Inc. All rights reserved.
|
3
|
+
// https://developers.google.com/protocol-buffers/
|
4
|
+
//
|
5
|
+
// Redistribution and use in source and binary forms, with or without
|
6
|
+
// modification, are permitted provided that the following conditions are
|
7
|
+
// met:
|
8
|
+
//
|
9
|
+
// * Redistributions of source code must retain the above copyright
|
10
|
+
// notice, this list of conditions and the following disclaimer.
|
11
|
+
// * Redistributions in binary form must reproduce the above
|
12
|
+
// copyright notice, this list of conditions and the following disclaimer
|
13
|
+
// in the documentation and/or other materials provided with the
|
14
|
+
// distribution.
|
15
|
+
// * Neither the name of Google Inc. nor the names of its
|
16
|
+
// contributors may be used to endorse or promote products derived from
|
17
|
+
// this software without specific prior written permission.
|
18
|
+
//
|
19
|
+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
20
|
+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
21
|
+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
22
|
+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
23
|
+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
24
|
+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
25
|
+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
26
|
+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
27
|
+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
28
|
+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
|
31
|
+
syntax = "proto3";
|
32
|
+
|
33
|
+
package google.protobuf;
|
34
|
+
|
35
|
+
option go_package = "google.golang.org/protobuf/types/known/anypb";
|
36
|
+
option java_package = "com.google.protobuf";
|
37
|
+
option java_outer_classname = "AnyProto";
|
38
|
+
option java_multiple_files = true;
|
39
|
+
option objc_class_prefix = "GPB";
|
40
|
+
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
|
41
|
+
|
42
|
+
// `Any` contains an arbitrary serialized protocol buffer message along with a
|
43
|
+
// URL that describes the type of the serialized message.
|
44
|
+
//
|
45
|
+
// Protobuf library provides support to pack/unpack Any values in the form
|
46
|
+
// of utility functions or additional generated methods of the Any type.
|
47
|
+
//
|
48
|
+
// Example 1: Pack and unpack a message in C++.
|
49
|
+
//
|
50
|
+
// Foo foo = ...;
|
51
|
+
// Any any;
|
52
|
+
// any.PackFrom(foo);
|
53
|
+
// ...
|
54
|
+
// if (any.UnpackTo(&foo)) {
|
55
|
+
// ...
|
56
|
+
// }
|
57
|
+
//
|
58
|
+
// Example 2: Pack and unpack a message in Java.
|
59
|
+
//
|
60
|
+
// Foo foo = ...;
|
61
|
+
// Any any = Any.pack(foo);
|
62
|
+
// ...
|
63
|
+
// if (any.is(Foo.class)) {
|
64
|
+
// foo = any.unpack(Foo.class);
|
65
|
+
// }
|
66
|
+
// // or ...
|
67
|
+
// if (any.isSameTypeAs(Foo.getDefaultInstance())) {
|
68
|
+
// foo = any.unpack(Foo.getDefaultInstance());
|
69
|
+
// }
|
70
|
+
//
|
71
|
+
// Example 3: Pack and unpack a message in Python.
|
72
|
+
//
|
73
|
+
// foo = Foo(...)
|
74
|
+
// any = Any()
|
75
|
+
// any.Pack(foo)
|
76
|
+
// ...
|
77
|
+
// if any.Is(Foo.DESCRIPTOR):
|
78
|
+
// any.Unpack(foo)
|
79
|
+
// ...
|
80
|
+
//
|
81
|
+
// Example 4: Pack and unpack a message in Go
|
82
|
+
//
|
83
|
+
// foo := &pb.Foo{...}
|
84
|
+
// any, err := anypb.New(foo)
|
85
|
+
// if err != nil {
|
86
|
+
// ...
|
87
|
+
// }
|
88
|
+
// ...
|
89
|
+
// foo := &pb.Foo{}
|
90
|
+
// if err := any.UnmarshalTo(foo); err != nil {
|
91
|
+
// ...
|
92
|
+
// }
|
93
|
+
//
|
94
|
+
// The pack methods provided by protobuf library will by default use
|
95
|
+
// 'type.googleapis.com/full.type.name' as the type URL and the unpack
|
96
|
+
// methods only use the fully qualified type name after the last '/'
|
97
|
+
// in the type URL, for example "foo.bar.com/x/y.z" will yield type
|
98
|
+
// name "y.z".
|
99
|
+
//
|
100
|
+
// JSON
|
101
|
+
// ====
|
102
|
+
// The JSON representation of an `Any` value uses the regular
|
103
|
+
// representation of the deserialized, embedded message, with an
|
104
|
+
// additional field `@type` which contains the type URL. Example:
|
105
|
+
//
|
106
|
+
// package google.profile;
|
107
|
+
// message Person {
|
108
|
+
// string first_name = 1;
|
109
|
+
// string last_name = 2;
|
110
|
+
// }
|
111
|
+
//
|
112
|
+
// {
|
113
|
+
// "@type": "type.googleapis.com/google.profile.Person",
|
114
|
+
// "firstName": <string>,
|
115
|
+
// "lastName": <string>
|
116
|
+
// }
|
117
|
+
//
|
118
|
+
// If the embedded message type is well-known and has a custom JSON
|
119
|
+
// representation, that representation will be embedded adding a field
|
120
|
+
// `value` which holds the custom JSON in addition to the `@type`
|
121
|
+
// field. Example (for message [google.protobuf.Duration][]):
|
122
|
+
//
|
123
|
+
// {
|
124
|
+
// "@type": "type.googleapis.com/google.protobuf.Duration",
|
125
|
+
// "value": "1.212s"
|
126
|
+
// }
|
127
|
+
//
|
128
|
+
message Any {
|
129
|
+
// A URL/resource name that uniquely identifies the type of the serialized
|
130
|
+
// protocol buffer message. This string must contain at least
|
131
|
+
// one "/" character. The last segment of the URL's path must represent
|
132
|
+
// the fully qualified name of the type (as in
|
133
|
+
// `path/google.protobuf.Duration`). The name should be in a canonical form
|
134
|
+
// (e.g., leading "." is not accepted).
|
135
|
+
//
|
136
|
+
// In practice, teams usually precompile into the binary all types that they
|
137
|
+
// expect it to use in the context of Any. However, for URLs which use the
|
138
|
+
// scheme `http`, `https`, or no scheme, one can optionally set up a type
|
139
|
+
// server that maps type URLs to message definitions as follows:
|
140
|
+
//
|
141
|
+
// * If no scheme is provided, `https` is assumed.
|
142
|
+
// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
|
143
|
+
// value in binary format, or produce an error.
|
144
|
+
// * Applications are allowed to cache lookup results based on the
|
145
|
+
// URL, or have them precompiled into a binary to avoid any
|
146
|
+
// lookup. Therefore, binary compatibility needs to be preserved
|
147
|
+
// on changes to types. (Use versioned type names to manage
|
148
|
+
// breaking changes.)
|
149
|
+
//
|
150
|
+
// Note: this functionality is not currently available in the official
|
151
|
+
// protobuf release, and it is not used for type URLs beginning with
|
152
|
+
// type.googleapis.com. As of May 2023, there are no widely used type server
|
153
|
+
// implementations and no plans to implement one.
|
154
|
+
//
|
155
|
+
// Schemes other than `http`, `https` (or the empty scheme) might be
|
156
|
+
// used with implementation specific semantics.
|
157
|
+
//
|
158
|
+
string type_url = 1;
|
159
|
+
|
160
|
+
// Must be a valid serialized protocol buffer of the above specified type.
|
161
|
+
bytes value = 2;
|
162
|
+
}
|