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
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
- info_string, objects_array = self.java_parser.parse_java_file(java_file_path)
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, java_file_path
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
- if dep not in self.processed_classes:
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
  推断简单类名的完整包名(通用算法,适用于任何应用)
@@ -190,7 +190,16 @@ class ProtoGenerator:
190
190
  Returns:
191
191
  消息定义的行列表
192
192
  """
193
- lines = [f'message {message_def.name} {{']
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
- lines = [f'enum {enum_def.name} {{']
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.Model -> com/example/model.proto
453
+ # com.example.Service$SkipRecovery -> com/example/service_skip_recovery.proto
454
+ # 注意:这里要使用完整的类名(包含$符号)来生成文件名,与实际文件名保持一致
422
455
  parts = class_name.split('.')
423
- proto_name = self._to_snake_case(parts[-1]) + '.proto'
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
- return field.type_name.split('.')[-1]
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
- return field.type_name
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
+ }