typia 7.0.0-dev.20241012 → 7.0.0-dev.20241019

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 (256) hide show
  1. package/lib/factories/JsonMetadataFactory.js +3 -2
  2. package/lib/factories/JsonMetadataFactory.js.map +1 -1
  3. package/lib/factories/MetadataCollection.d.ts +3 -3
  4. package/lib/factories/MetadataCollection.js +2 -2
  5. package/lib/factories/MetadataCollection.js.map +1 -1
  6. package/lib/factories/MetadataFactory.d.ts +2 -2
  7. package/lib/factories/MetadataFactory.js +3 -3
  8. package/lib/factories/MetadataFactory.js.map +1 -1
  9. package/lib/factories/MetadataTypeTagFactory.d.ts +3 -2
  10. package/lib/factories/MetadataTypeTagFactory.js +26 -3
  11. package/lib/factories/MetadataTypeTagFactory.js.map +1 -1
  12. package/lib/factories/ProtobufFactory.js +1266 -160
  13. package/lib/factories/ProtobufFactory.js.map +1 -1
  14. package/lib/factories/internal/metadata/IMetadataIteratorProps.d.ts +1 -0
  15. package/lib/factories/internal/metadata/MetadataHelper.js +1 -1
  16. package/lib/factories/internal/metadata/MetadataHelper.js.map +1 -1
  17. package/lib/factories/internal/metadata/emplace_metadata_alias.d.ts +2 -2
  18. package/lib/factories/internal/metadata/emplace_metadata_object.js +5 -5
  19. package/lib/factories/internal/metadata/emplace_metadata_object.js.map +1 -1
  20. package/lib/factories/internal/metadata/explore_metadata.js +2 -0
  21. package/lib/factories/internal/metadata/explore_metadata.js.map +1 -1
  22. package/lib/factories/internal/metadata/iterate_metadata.js +1 -1
  23. package/lib/factories/internal/metadata/iterate_metadata.js.map +1 -1
  24. package/lib/factories/internal/metadata/iterate_metadata_alias.js +8 -2
  25. package/lib/factories/internal/metadata/iterate_metadata_alias.js.map +1 -1
  26. package/lib/factories/internal/metadata/iterate_metadata_collection.js +6 -6
  27. package/lib/factories/internal/metadata/iterate_metadata_collection.js.map +1 -1
  28. package/lib/factories/internal/metadata/iterate_metadata_intersection.js +262 -137
  29. package/lib/factories/internal/metadata/iterate_metadata_intersection.js.map +1 -1
  30. package/lib/factories/internal/metadata/iterate_metadata_map.js +4 -2
  31. package/lib/factories/internal/metadata/iterate_metadata_map.js.map +1 -1
  32. package/lib/factories/internal/metadata/iterate_metadata_native.js +27 -11
  33. package/lib/factories/internal/metadata/iterate_metadata_native.js.map +1 -1
  34. package/lib/factories/internal/metadata/iterate_metadata_set.js +8 -1
  35. package/lib/factories/internal/metadata/iterate_metadata_set.js.map +1 -1
  36. package/lib/factories/internal/metadata/iterate_metadata_sort.js +1 -1
  37. package/lib/factories/internal/metadata/iterate_metadata_sort.js.map +1 -1
  38. package/lib/factories/internal/metadata/iterate_metadata_template.js +1 -1
  39. package/lib/factories/internal/metadata/iterate_metadata_template.js.map +1 -1
  40. package/lib/programmers/CheckerProgrammer.js +5 -5
  41. package/lib/programmers/CheckerProgrammer.js.map +1 -1
  42. package/lib/programmers/RandomProgrammer.js +12 -12
  43. package/lib/programmers/RandomProgrammer.js.map +1 -1
  44. package/lib/programmers/helpers/AtomicPredicator.js +3 -3
  45. package/lib/programmers/helpers/AtomicPredicator.js.map +1 -1
  46. package/lib/programmers/helpers/ProtobufUtil.d.ts +6 -3
  47. package/lib/programmers/helpers/ProtobufUtil.js +216 -93
  48. package/lib/programmers/helpers/ProtobufUtil.js.map +1 -1
  49. package/lib/programmers/helpers/UnionExplorer.d.ts +4 -2
  50. package/lib/programmers/helpers/UnionExplorer.js +1 -1
  51. package/lib/programmers/helpers/UnionExplorer.js.map +1 -1
  52. package/lib/programmers/http/HttpFormDataProgrammer.js +6 -6
  53. package/lib/programmers/http/HttpFormDataProgrammer.js.map +1 -1
  54. package/lib/programmers/internal/application_escaped.js +2 -2
  55. package/lib/programmers/internal/application_escaped.js.map +1 -1
  56. package/lib/programmers/internal/application_v30_alias.js +13 -8
  57. package/lib/programmers/internal/application_v30_alias.js.map +1 -1
  58. package/lib/programmers/internal/application_v30_native.js +17 -10
  59. package/lib/programmers/internal/application_v30_native.js.map +1 -1
  60. package/lib/programmers/internal/application_v30_object.js +16 -6
  61. package/lib/programmers/internal/application_v30_object.js.map +1 -1
  62. package/lib/programmers/internal/application_v30_schema.js +24 -17
  63. package/lib/programmers/internal/application_v30_schema.js.map +1 -1
  64. package/lib/programmers/internal/application_v31_alias.js +12 -11
  65. package/lib/programmers/internal/application_v31_alias.js.map +1 -1
  66. package/lib/programmers/internal/application_v31_native.js +17 -10
  67. package/lib/programmers/internal/application_v31_native.js.map +1 -1
  68. package/lib/programmers/internal/application_v31_object.js +13 -6
  69. package/lib/programmers/internal/application_v31_object.js.map +1 -1
  70. package/lib/programmers/internal/application_v31_schema.js +23 -16
  71. package/lib/programmers/internal/application_v31_schema.js.map +1 -1
  72. package/lib/programmers/internal/check_dynamic_key.js +4 -4
  73. package/lib/programmers/internal/check_dynamic_key.js.map +1 -1
  74. package/lib/programmers/internal/check_native.js +3 -3
  75. package/lib/programmers/internal/check_union_array_like.js.map +1 -1
  76. package/lib/programmers/internal/llm_schema_escaped.js +2 -2
  77. package/lib/programmers/internal/llm_schema_escaped.js.map +1 -1
  78. package/lib/programmers/internal/llm_schema_object.js +18 -14
  79. package/lib/programmers/internal/llm_schema_object.js.map +1 -1
  80. package/lib/programmers/internal/llm_schema_station.js +8 -8
  81. package/lib/programmers/internal/llm_schema_station.js.map +1 -1
  82. package/lib/programmers/json/JsonSchemasProgrammer.js +5 -5
  83. package/lib/programmers/json/JsonSchemasProgrammer.js.map +1 -1
  84. package/lib/programmers/json/JsonStringifyProgrammer.js +18 -17
  85. package/lib/programmers/json/JsonStringifyProgrammer.js.map +1 -1
  86. package/lib/programmers/llm/LlmSchemaProgrammer.js +6 -6
  87. package/lib/programmers/llm/LlmSchemaProgrammer.js.map +1 -1
  88. package/lib/programmers/misc/MiscCloneProgrammer.js +7 -5
  89. package/lib/programmers/misc/MiscCloneProgrammer.js.map +1 -1
  90. package/lib/programmers/misc/MiscPruneProgrammer.js +1 -1
  91. package/lib/programmers/misc/MiscPruneProgrammer.js.map +1 -1
  92. package/lib/programmers/notations/NotationGeneralProgrammer.js +6 -4
  93. package/lib/programmers/notations/NotationGeneralProgrammer.js.map +1 -1
  94. package/lib/programmers/protobuf/ProtobufDecodeProgrammer.js +169 -220
  95. package/lib/programmers/protobuf/ProtobufDecodeProgrammer.js.map +1 -1
  96. package/lib/programmers/protobuf/ProtobufEncodeProgrammer.js +6 -4
  97. package/lib/programmers/protobuf/ProtobufEncodeProgrammer.js.map +1 -1
  98. package/lib/programmers/protobuf/ProtobufMessageProgrammer.d.ts +1 -1
  99. package/lib/programmers/protobuf/ProtobufMessageProgrammer.js +53 -128
  100. package/lib/programmers/protobuf/ProtobufMessageProgrammer.js.map +1 -1
  101. package/lib/schemas/metadata/IMetadata.d.ts +14 -18
  102. package/lib/schemas/metadata/IMetadataAlias.d.ts +2 -7
  103. package/lib/schemas/metadata/IMetadataAliasType.d.ts +10 -0
  104. package/lib/schemas/metadata/IMetadataAliasType.js +3 -0
  105. package/lib/schemas/metadata/IMetadataAliasType.js.map +1 -0
  106. package/lib/schemas/metadata/IMetadataComponents.d.ts +2 -2
  107. package/lib/schemas/metadata/IMetadataConstantValue.d.ts +1 -1
  108. package/lib/schemas/metadata/IMetadataDictionary.d.ts +2 -2
  109. package/lib/schemas/metadata/IMetadataMap.d.ts +7 -0
  110. package/lib/schemas/metadata/{IMetadataEntry.js → IMetadataMap.js} +1 -1
  111. package/lib/schemas/metadata/IMetadataMap.js.map +1 -0
  112. package/lib/schemas/metadata/IMetadataNative.d.ts +5 -0
  113. package/lib/schemas/metadata/IMetadataNative.js +3 -0
  114. package/lib/schemas/metadata/IMetadataNative.js.map +1 -0
  115. package/lib/schemas/metadata/IMetadataSet.d.ts +6 -0
  116. package/lib/schemas/metadata/IMetadataSet.js +3 -0
  117. package/lib/schemas/metadata/IMetadataSet.js.map +1 -0
  118. package/lib/schemas/metadata/IMetadataTemplate.d.ts +1 -1
  119. package/lib/schemas/metadata/IMetadataTypeTag.d.ts +1 -1
  120. package/lib/schemas/metadata/Metadata.d.ts +6 -9
  121. package/lib/schemas/metadata/Metadata.js +136 -98
  122. package/lib/schemas/metadata/Metadata.js.map +1 -1
  123. package/lib/schemas/metadata/MetadataAlias.d.ts +8 -11
  124. package/lib/schemas/metadata/MetadataAlias.js +48 -33
  125. package/lib/schemas/metadata/MetadataAlias.js.map +1 -1
  126. package/lib/schemas/metadata/MetadataAliasType.d.ts +16 -0
  127. package/lib/schemas/metadata/MetadataAliasType.js +51 -0
  128. package/lib/schemas/metadata/MetadataAliasType.js.map +1 -0
  129. package/lib/schemas/metadata/MetadataComponents.d.ts +2 -2
  130. package/lib/schemas/metadata/MetadataComponents.js +2 -2
  131. package/lib/schemas/metadata/MetadataComponents.js.map +1 -1
  132. package/lib/schemas/metadata/MetadataConstantValue.d.ts +1 -1
  133. package/lib/schemas/metadata/MetadataMap.d.ts +14 -0
  134. package/lib/schemas/metadata/MetadataMap.js +66 -0
  135. package/lib/schemas/metadata/MetadataMap.js.map +1 -0
  136. package/lib/schemas/metadata/MetadataNative.d.ts +12 -0
  137. package/lib/schemas/metadata/MetadataNative.js +65 -0
  138. package/lib/schemas/metadata/MetadataNative.js.map +1 -0
  139. package/lib/schemas/metadata/MetadataProperty.d.ts +2 -0
  140. package/lib/schemas/metadata/MetadataProperty.js.map +1 -1
  141. package/lib/schemas/metadata/MetadataSet.d.ts +13 -0
  142. package/lib/schemas/metadata/MetadataSet.js +64 -0
  143. package/lib/schemas/metadata/MetadataSet.js.map +1 -0
  144. package/lib/schemas/metadata/MetadataTemplate.d.ts +1 -1
  145. package/lib/schemas/protobuf/IProtobufProperty.d.ts +5 -0
  146. package/lib/schemas/protobuf/IProtobufProperty.js +3 -0
  147. package/lib/schemas/protobuf/IProtobufProperty.js.map +1 -0
  148. package/lib/schemas/protobuf/IProtobufPropertyType.d.ts +28 -0
  149. package/lib/schemas/protobuf/IProtobufPropertyType.js +3 -0
  150. package/lib/schemas/protobuf/IProtobufPropertyType.js.map +1 -0
  151. package/lib/schemas/protobuf/IProtobufSchema.d.ts +38 -0
  152. package/lib/schemas/protobuf/IProtobufSchema.js +3 -0
  153. package/lib/schemas/protobuf/IProtobufSchema.js.map +1 -0
  154. package/lib/tags/Example.d.ts +2 -2
  155. package/lib/tags/Examples.d.ts +2 -2
  156. package/lib/tags/JsonSchemaPlugin.d.ts +1 -1
  157. package/lib/tags/Sequence.d.ts +9 -0
  158. package/lib/tags/Sequence.js +3 -0
  159. package/lib/tags/Sequence.js.map +1 -0
  160. package/lib/tags/TagBase.d.ts +1 -1
  161. package/lib/tags/index.d.ts +1 -0
  162. package/lib/tags/index.js +1 -0
  163. package/lib/tags/index.js.map +1 -1
  164. package/lib/utils/{NameEncoder.d.ts → ProtobufNameEncoder.d.ts} +1 -1
  165. package/lib/utils/{NameEncoder.js → ProtobufNameEncoder.js} +7 -7
  166. package/lib/utils/ProtobufNameEncoder.js.map +1 -0
  167. package/package.json +1 -1
  168. package/src/factories/JsonMetadataFactory.ts +5 -2
  169. package/src/factories/MetadataCollection.ts +6 -6
  170. package/src/factories/MetadataFactory.ts +7 -7
  171. package/src/factories/MetadataTypeTagFactory.ts +31 -6
  172. package/src/factories/ProtobufFactory.ts +794 -177
  173. package/src/factories/internal/metadata/IMetadataIteratorProps.ts +1 -0
  174. package/src/factories/internal/metadata/MetadataHelper.ts +1 -1
  175. package/src/factories/internal/metadata/emplace_metadata_alias.ts +2 -2
  176. package/src/factories/internal/metadata/emplace_metadata_object.ts +5 -5
  177. package/src/factories/internal/metadata/explore_metadata.ts +1 -0
  178. package/src/factories/internal/metadata/iterate_metadata.ts +1 -1
  179. package/src/factories/internal/metadata/iterate_metadata_alias.ts +9 -4
  180. package/src/factories/internal/metadata/iterate_metadata_collection.ts +6 -6
  181. package/src/factories/internal/metadata/iterate_metadata_intersection.ts +163 -181
  182. package/src/factories/internal/metadata/iterate_metadata_map.ts +5 -2
  183. package/src/factories/internal/metadata/iterate_metadata_native.ts +20 -2
  184. package/src/factories/internal/metadata/iterate_metadata_set.ts +27 -11
  185. package/src/factories/internal/metadata/iterate_metadata_sort.ts +1 -1
  186. package/src/factories/internal/metadata/iterate_metadata_template.ts +1 -3
  187. package/src/programmers/CheckerProgrammer.ts +9 -7
  188. package/src/programmers/RandomProgrammer.ts +16 -14
  189. package/src/programmers/helpers/AtomicPredicator.ts +3 -3
  190. package/src/programmers/helpers/ProtobufUtil.ts +147 -44
  191. package/src/programmers/helpers/UnionExplorer.ts +62 -62
  192. package/src/programmers/http/HttpFormDataProgrammer.ts +10 -6
  193. package/src/programmers/internal/application_escaped.ts +2 -2
  194. package/src/programmers/internal/application_v30_alias.ts +18 -12
  195. package/src/programmers/internal/application_v30_native.ts +22 -12
  196. package/src/programmers/internal/application_v30_object.ts +23 -8
  197. package/src/programmers/internal/application_v30_schema.ts +31 -34
  198. package/src/programmers/internal/application_v31_alias.ts +16 -13
  199. package/src/programmers/internal/application_v31_native.ts +22 -12
  200. package/src/programmers/internal/application_v31_object.ts +19 -8
  201. package/src/programmers/internal/application_v31_schema.ts +26 -29
  202. package/src/programmers/internal/check_dynamic_key.ts +4 -4
  203. package/src/programmers/internal/check_native.ts +4 -4
  204. package/src/programmers/internal/check_union_array_like.ts +2 -1
  205. package/src/programmers/internal/llm_schema_escaped.ts +2 -2
  206. package/src/programmers/internal/llm_schema_object.ts +21 -18
  207. package/src/programmers/internal/llm_schema_station.ts +9 -11
  208. package/src/programmers/json/JsonSchemasProgrammer.ts +5 -5
  209. package/src/programmers/json/JsonStringifyProgrammer.ts +5 -5
  210. package/src/programmers/llm/LlmSchemaProgrammer.ts +6 -6
  211. package/src/programmers/misc/MiscCloneProgrammer.ts +11 -7
  212. package/src/programmers/misc/MiscPruneProgrammer.ts +1 -1
  213. package/src/programmers/notations/NotationGeneralProgrammer.ts +10 -6
  214. package/src/programmers/protobuf/ProtobufDecodeProgrammer.ts +254 -308
  215. package/src/programmers/protobuf/ProtobufEncodeProgrammer.ts +11 -8
  216. package/src/programmers/protobuf/ProtobufMessageProgrammer.ts +73 -95
  217. package/src/schemas/metadata/IMetadata.ts +35 -39
  218. package/src/schemas/metadata/IMetadataAlias.ts +6 -12
  219. package/src/schemas/metadata/IMetadataAliasType.ts +12 -0
  220. package/src/schemas/metadata/IMetadataArray.ts +6 -6
  221. package/src/schemas/metadata/IMetadataComponents.ts +11 -11
  222. package/src/schemas/metadata/IMetadataConstantValue.ts +1 -1
  223. package/src/schemas/metadata/IMetadataDictionary.ts +2 -2
  224. package/src/schemas/metadata/IMetadataMap.ts +8 -0
  225. package/src/schemas/metadata/IMetadataNative.ts +6 -0
  226. package/src/schemas/metadata/IMetadataObjectType.ts +13 -13
  227. package/src/schemas/metadata/IMetadataSet.ts +7 -0
  228. package/src/schemas/metadata/IMetadataTemplate.ts +7 -7
  229. package/src/schemas/metadata/IMetadataTuple.ts +6 -6
  230. package/src/schemas/metadata/IMetadataTypeTag.ts +16 -16
  231. package/src/schemas/metadata/Metadata.ts +100 -47
  232. package/src/schemas/metadata/MetadataAlias.ts +46 -61
  233. package/src/schemas/metadata/MetadataAliasType.ts +63 -0
  234. package/src/schemas/metadata/MetadataArray.ts +49 -49
  235. package/src/schemas/metadata/MetadataComponents.ts +3 -3
  236. package/src/schemas/metadata/MetadataConstantValue.ts +1 -1
  237. package/src/schemas/metadata/MetadataMap.ts +48 -0
  238. package/src/schemas/metadata/MetadataNative.ts +44 -0
  239. package/src/schemas/metadata/MetadataProperty.ts +3 -0
  240. package/src/schemas/metadata/MetadataSet.ts +45 -0
  241. package/src/schemas/metadata/MetadataTemplate.ts +80 -80
  242. package/src/schemas/metadata/MetadataTuple.ts +32 -32
  243. package/src/schemas/protobuf/IProtobufProperty.ts +6 -0
  244. package/src/schemas/protobuf/IProtobufPropertyType.ts +37 -0
  245. package/src/schemas/protobuf/IProtobufSchema.ts +50 -0
  246. package/src/tags/Example.ts +24 -17
  247. package/src/tags/Examples.ts +16 -16
  248. package/src/tags/JsonSchemaPlugin.ts +8 -8
  249. package/src/tags/Sequence.ts +10 -0
  250. package/src/tags/TagBase.ts +82 -76
  251. package/src/tags/index.ts +1 -0
  252. package/src/utils/{NameEncoder.ts → ProtobufNameEncoder.ts} +1 -1
  253. package/lib/schemas/metadata/IMetadataEntry.d.ts +0 -5
  254. package/lib/schemas/metadata/IMetadataEntry.js.map +0 -1
  255. package/lib/utils/NameEncoder.js.map +0 -1
  256. package/src/schemas/metadata/IMetadataEntry.ts +0 -6
@@ -1,12 +1,18 @@
1
1
  import ts from "typescript";
2
2
 
3
+ import { IMetadataTypeTag } from "../schemas/metadata/IMetadataTypeTag";
3
4
  import { Metadata } from "../schemas/metadata/Metadata";
4
5
  import { MetadataObjectType } from "../schemas/metadata/MetadataObjectType";
6
+ import { MetadataProperty } from "../schemas/metadata/MetadataProperty";
7
+ import { IProtobufProperty } from "../schemas/protobuf/IProtobufProperty";
8
+ import { IProtobufPropertyType } from "../schemas/protobuf/IProtobufPropertyType";
9
+ import { IProtobufSchema } from "../schemas/protobuf/IProtobufSchema";
5
10
 
6
11
  import { ProtobufUtil } from "../programmers/helpers/ProtobufUtil";
7
12
 
8
13
  import { TransformerError } from "../transformers/TransformerError";
9
14
 
15
+ import { ProtobufAtomic } from "../typings/ProtobufAtomic";
10
16
  import { ValidationPipe } from "../typings/ValidationPipe";
11
17
 
12
18
  import { MetadataCollection } from "./MetadataCollection";
@@ -21,6 +27,9 @@ export namespace ProtobufFactory {
21
27
  type: ts.Type;
22
28
  }
23
29
 
30
+ /* -----------------------------------------------------------
31
+ METADATA COMPOSER
32
+ ----------------------------------------------------------- */
24
33
  export const metadata = (props: IProps): Metadata => {
25
34
  // COMPOSE METADATA WITH INDIVIDUAL VALIDATIONS
26
35
  const result: ValidationPipe<Metadata, MetadataFactory.IError> =
@@ -31,7 +40,7 @@ export namespace ProtobufFactory {
31
40
  escape: false,
32
41
  constant: true,
33
42
  absorb: true,
34
- validate,
43
+ validate: validate(),
35
44
  },
36
45
  });
37
46
  if (result.success === false)
@@ -42,192 +51,791 @@ export namespace ProtobufFactory {
42
51
  return result.data;
43
52
  };
44
53
 
45
- const validate = (
54
+ /**
55
+ * @internal
56
+ */
57
+ export const emplaceObject = (object: MetadataObjectType): void => {
58
+ for (const p of object.properties) emplaceProperty(p);
59
+ const properties: IProtobufProperty[] = object.properties
60
+ .map((p) => p.of_protobuf_)
61
+ .filter((p) => p !== undefined);
62
+ const unique: Set<number> = new Set(
63
+ properties
64
+ .filter((p) => p !== undefined)
65
+ .filter((p) => p.fixed === true)
66
+ .map((p) => p.union.map((u) => u.index))
67
+ .flat(),
68
+ );
69
+ let index: number = 1;
70
+ properties.forEach((schema) => {
71
+ if (schema.fixed === true)
72
+ index = Math.max(
73
+ index,
74
+ Math.max(...schema.union.map((u) => u.index)) + 1,
75
+ );
76
+ else {
77
+ for (const u of schema.union) {
78
+ while (unique.has(index) === true) ++index;
79
+ u.index = index;
80
+ unique.add(index);
81
+ }
82
+ ++index;
83
+ }
84
+ });
85
+ };
86
+
87
+ const emplaceProperty = (prop: MetadataProperty): void => {
88
+ const union: IProtobufPropertyType[] = [];
89
+ for (const native of prop.value.natives)
90
+ if (native.name === "Uint8Array")
91
+ union.push({
92
+ type: "bytes",
93
+ index: ProtobufUtil.getSequence(native.tags[0] ?? [])!,
94
+ });
95
+ union.push(...emplaceAtomic(prop.value).values());
96
+ for (const array of prop.value.arrays)
97
+ union.push({
98
+ type: "array",
99
+ array: array.type,
100
+ value: emplaceSchema(
101
+ array.type.value,
102
+ ) as IProtobufSchema.IArray["value"],
103
+ index: ProtobufUtil.getSequence(array.tags[0] ?? [])!,
104
+ });
105
+ for (const obj of prop.value.objects)
106
+ if (isDynamicObject(obj.type))
107
+ union.push({
108
+ type: "map",
109
+ map: obj.type,
110
+ key: emplaceSchema(
111
+ obj.type.properties[0]!.key,
112
+ ) as IProtobufSchema.IMap["key"],
113
+ value: emplaceSchema(
114
+ obj.type.properties[0]!.value,
115
+ ) as IProtobufSchema.IMap["value"],
116
+ index: ProtobufUtil.getSequence(obj.tags[0] ?? [])!,
117
+ });
118
+ else
119
+ union.push({
120
+ type: "object",
121
+ object: obj.type,
122
+ index: ProtobufUtil.getSequence(obj.tags[0] ?? [])!,
123
+ });
124
+ for (const map of prop.value.maps)
125
+ union.push({
126
+ type: "map",
127
+ map,
128
+ key: emplaceSchema(map.key) as IProtobufSchema.IMap["key"],
129
+ value: emplaceSchema(map.value) as IProtobufSchema.IMap["value"],
130
+ index: ProtobufUtil.getSequence(map.tags[0] ?? [])!,
131
+ });
132
+ prop.of_protobuf_ = {
133
+ union,
134
+ fixed: union.every((p) => p.index !== null),
135
+ };
136
+ };
137
+
138
+ const emplaceSchema = (metadata: Metadata): IProtobufSchema => {
139
+ for (const native of metadata.natives)
140
+ if (native.name === "Uint8Array")
141
+ return {
142
+ type: "bytes",
143
+ };
144
+ const atomic = emplaceAtomic(metadata);
145
+ if (atomic.size) return atomic.values().next().value!;
146
+ for (const array of metadata.arrays)
147
+ return {
148
+ type: "array",
149
+ array: array.type,
150
+ value: emplaceSchema(
151
+ array.type.value,
152
+ ) as IProtobufSchema.IArray["value"],
153
+ };
154
+ for (const obj of metadata.objects)
155
+ if (isDynamicObject(obj.type))
156
+ return {
157
+ type: "map",
158
+ map: obj.type,
159
+ key: emplaceSchema(
160
+ obj.type.properties[0]!.key,
161
+ ) as IProtobufSchema.IMap["key"],
162
+ value: emplaceSchema(
163
+ obj.type.properties[0]!.value,
164
+ ) as IProtobufSchema.IMap["value"],
165
+ };
166
+ else
167
+ return {
168
+ type: "object",
169
+ object: obj.type,
170
+ };
171
+ for (const map of metadata.maps)
172
+ return {
173
+ type: "map",
174
+ map,
175
+ key: emplaceSchema(map.key) as IProtobufSchema.IMap["key"],
176
+ value: emplaceSchema(map.value) as IProtobufSchema.IMap["value"],
177
+ };
178
+ throw new Error(
179
+ "Error on ProtobufFactory.emplaceSchema(): any type detected.",
180
+ );
181
+ };
182
+
183
+ const emplaceAtomic = (
46
184
  meta: Metadata,
47
- explore: MetadataFactory.IExplore,
48
- ): string[] => {
49
- const errors: string[] = [];
50
- const insert = (msg: string) => errors.push(msg);
51
-
52
- if (explore.top === true) {
53
- const onlyObject: boolean =
54
- meta.size() === 1 &&
55
- meta.objects.length === 1 &&
56
- meta.objects[0]!.type.properties.every((p) => p.key.isSoleLiteral()) &&
57
- meta.isRequired() === true &&
58
- meta.nullable === false;
59
- if (onlyObject === false)
60
- insert("target type must be a sole and static object type");
185
+ ): Map<ProtobufAtomic, IProtobufPropertyType> => {
186
+ const map: Map<ProtobufAtomic, IProtobufPropertyType> = new Map();
187
+
188
+ // CONSTANTS
189
+ for (const c of meta.constants)
190
+ if (c.type === "boolean")
191
+ map.set("bool", {
192
+ type: "bool",
193
+ index: getSequence(c.values[0]?.tags[0] ?? [])!,
194
+ });
195
+ else if (c.type === "bigint") {
196
+ const init: ProtobufAtomic.BigNumeric = getBigintType(
197
+ c.values.map((v) => BigInt(v.value)),
198
+ );
199
+ for (const value of c.values)
200
+ emplaceBigint({
201
+ map,
202
+ tags: value.tags,
203
+ init,
204
+ });
205
+ } else if (c.type === "number") {
206
+ const init: ProtobufAtomic.Numeric = getNumberType(
207
+ c.values.map((v) => v.value) as number[],
208
+ );
209
+ for (const value of c.values)
210
+ emplaceNumber({
211
+ map,
212
+ tags: value.tags,
213
+ init,
214
+ });
215
+ } else if (c.type === "string")
216
+ map.set("string", {
217
+ type: "string",
218
+ index: getSequence(c.values[0]?.tags[0] ?? [])!,
219
+ });
220
+
221
+ // TEMPLATE
222
+ if (meta.templates.length)
223
+ map.set("string", {
224
+ type: "string",
225
+ index: getSequence(meta.templates[0]?.tags[0] ?? [])!,
226
+ });
227
+
228
+ // ATOMICS
229
+ for (const atomic of meta.atomics)
230
+ if (atomic.type === "boolean")
231
+ map.set("bool", {
232
+ type: "bool",
233
+ index: getSequence(atomic.tags[0] ?? [])!,
234
+ });
235
+ else if (atomic.type === "bigint")
236
+ emplaceBigint({
237
+ map,
238
+ tags: atomic.tags,
239
+ init: "int64",
240
+ });
241
+ else if (atomic.type === "number")
242
+ emplaceNumber({
243
+ map,
244
+ tags: atomic.tags,
245
+ init: "double",
246
+ });
247
+ else if (atomic.type === "string")
248
+ map.set("string", {
249
+ type: "string",
250
+ index: getSequence(atomic.tags[0] ?? [])!,
251
+ });
252
+
253
+ // SORTING IF REQUIRED
254
+ if (map.size && map.values().next().value!.index === null)
255
+ return new Map(
256
+ Array.from(map).sort((x, y) => ProtobufUtil.compare(x[0], y[0])),
257
+ );
258
+ return map;
259
+ };
260
+
261
+ const emplaceBigint = (next: {
262
+ map: Map<ProtobufAtomic, IProtobufPropertyType>;
263
+ tags: IMetadataTypeTag[][];
264
+ init: ProtobufAtomic.BigNumeric;
265
+ }): void => {
266
+ if (next.tags.length === 0) {
267
+ next.map.set(next.init, {
268
+ type: "bigint",
269
+ name: next.init,
270
+ index: null!,
271
+ });
272
+ return;
61
273
  }
274
+ for (const row of next.tags) {
275
+ const value: ProtobufAtomic.BigNumeric =
276
+ row.find(
277
+ (tag) =>
278
+ tag.kind === "type" &&
279
+ (tag.value === "int64" || tag.value === "uint64"),
280
+ )?.value ?? next.init;
281
+ next.map.set(next.init, {
282
+ type: "bigint",
283
+ name: value,
284
+ index: ProtobufUtil.getSequence(row)!,
285
+ });
286
+ }
287
+ };
62
288
 
63
- //----
64
- // NOT SUPPORTED TYPES
65
- //----
66
- const noSupport = (msg: string) => insert(`does not support ${msg}`);
67
-
68
- // PROHIBIT ANY TYPE
69
- if (meta.any) noSupport("any type");
70
- // PROHIBIT FUNCTIONAL TYPE
71
- if (meta.functions.length) noSupport("functional type");
72
- // PROHIBIT TUPLE TYPE
73
- if (meta.tuples.length) noSupport("tuple type");
74
- // PROHIBIT SET TYPE
75
- if (meta.sets.length) noSupport("Set type");
76
- // NATIVE TYPE, BUT NOT Uint8Array
77
- if (meta.natives.length)
78
- for (const native of meta.natives) {
79
- if (native === "Uint8Array") continue;
80
-
81
- const instead = BANNED_NATIVE_TYPES.get(native);
82
- if (instead === undefined) noSupport(`${native} type`);
83
- else noSupport(`${native} type. Use ${instead} type instead.`);
84
- }
85
- //----
86
- // ATOMIC CASES
87
- //----
88
- if (meta.atomics.length) {
89
- const numbers = ProtobufUtil.getNumbers(meta);
90
- const bigints = ProtobufUtil.getBigints(meta);
91
-
92
- for (const type of ["int64", "uint64"])
93
- if (numbers.some((n) => n === type) && bigints.some((b) => b === type))
94
- insert(
95
- `tags.Type<"${type}"> cannot be used in both number and bigint types. Recommend to remove from number type`,
96
- );
289
+ const emplaceNumber = (next: {
290
+ map: Map<ProtobufAtomic, IProtobufPropertyType>;
291
+ tags: IMetadataTypeTag[][];
292
+ init: ProtobufAtomic.Numeric;
293
+ }): void => {
294
+ if (next.tags.length === 0) {
295
+ next.map.set(next.init, {
296
+ type: "number",
297
+ name: next.init,
298
+ index: null!,
299
+ });
300
+ return;
301
+ }
302
+ for (const row of next.tags) {
303
+ const value: ProtobufAtomic.Numeric =
304
+ row.find(
305
+ (tag) =>
306
+ tag.kind === "type" &&
307
+ (tag.value === "int32" ||
308
+ tag.value === "uint32" ||
309
+ tag.value === "int64" ||
310
+ tag.value === "uint64" ||
311
+ tag.value === "float" ||
312
+ tag.value === "double"),
313
+ )?.value ?? next.init;
314
+ next.map.set(value, {
315
+ type: "number",
316
+ name: value,
317
+ index: ProtobufUtil.getSequence(row)!,
318
+ });
97
319
  }
98
- //----
99
- // ARRRAY CASES
100
- //----
101
- // DO NOT ALLOW MULTI-DIMENTIONAL ARRAY
102
- if (
103
- meta.arrays.length &&
104
- meta.arrays.some((array) => !!array.type.value.arrays.length)
105
- )
106
- noSupport("over two dimenstional array type");
107
- // CHILD OF ARRAY TYPE MUST BE REQUIRED
108
- if (
109
- meta.arrays.length &&
110
- meta.arrays.some(
111
- (array) =>
112
- array.type.value.isRequired() === false ||
113
- array.type.value.nullable === true,
320
+ };
321
+
322
+ const getBigintType = (values: bigint[]): ProtobufAtomic.BigNumeric =>
323
+ values.some((v) => v < 0) ? "int64" : "uint64";
324
+
325
+ const getNumberType = (values: number[]): ProtobufAtomic.Numeric =>
326
+ values.every((v) => Math.floor(v) === v)
327
+ ? values.every((v) => -2147483648 <= v && v <= 2147483647)
328
+ ? "int32"
329
+ : "int64"
330
+ : "double";
331
+
332
+ const getSequence = (tags: IMetadataTypeTag[]): number | null => {
333
+ const sequence = tags.find(
334
+ (t) =>
335
+ t.kind === "sequence" &&
336
+ typeof (t.schema as any)?.["x-protobuf-sequence"] === "number",
337
+ );
338
+ if (sequence === undefined) return null;
339
+ const value: number = Number(
340
+ (sequence.schema as any)["x-protobuf-sequence"],
341
+ );
342
+ return Number.isNaN(value) ? null : value;
343
+ };
344
+
345
+ /* -----------------------------------------------------------
346
+ VALIDATORS
347
+ ----------------------------------------------------------- */
348
+ const validate = () => {
349
+ const visited: WeakSet<MetadataObjectType> = new WeakSet();
350
+ return (meta: Metadata, explore: MetadataFactory.IExplore): string[] => {
351
+ const errors: string[] = [];
352
+ const insert = (msg: string) => errors.push(msg);
353
+
354
+ if (explore.top === true) {
355
+ const onlyObject: boolean =
356
+ meta.size() === 1 &&
357
+ meta.objects.length === 1 &&
358
+ meta.objects[0]!.type.properties.every((p) =>
359
+ p.key.isSoleLiteral(),
360
+ ) &&
361
+ meta.isRequired() === true &&
362
+ meta.nullable === false;
363
+ if (onlyObject === false)
364
+ insert("target type must be a sole and static object type");
365
+ }
366
+ if (explore.object !== null && visited.has(explore.object) === false) {
367
+ visited.add(explore.object);
368
+ validateObject({
369
+ object: explore.object,
370
+ errors,
371
+ });
372
+ try {
373
+ emplaceObject(explore.object);
374
+ } catch {}
375
+ }
376
+
377
+ //----
378
+ // NOT SUPPORTED TYPES
379
+ //----
380
+ const noSupport = (msg: string) => insert(`does not support ${msg}`);
381
+
382
+ // PROHIBIT ANY TYPE
383
+ if (meta.any) noSupport("any type");
384
+ // PROHIBIT FUNCTIONAL TYPE
385
+ if (meta.functions.length) noSupport("functional type");
386
+ // PROHIBIT TUPLE TYPE
387
+ if (meta.tuples.length) noSupport("tuple type");
388
+ // PROHIBIT SET TYPE
389
+ if (meta.sets.length) noSupport("Set type");
390
+ // NATIVE TYPE, BUT NOT Uint8Array
391
+ if (meta.natives.length)
392
+ for (const native of meta.natives) {
393
+ if (native.name === "Uint8Array") continue;
394
+
395
+ const instead = BANNED_NATIVE_TYPES.get(native.name);
396
+ if (instead === undefined) noSupport(`${native.name} type`);
397
+ else noSupport(`${native.name} type. Use ${instead} type instead.`);
398
+ }
399
+ //----
400
+ // ATOMIC CASES
401
+ //----
402
+ if (meta.atomics.length) {
403
+ const numbers = ProtobufUtil.getNumbers(meta);
404
+ const bigints = ProtobufUtil.getBigints(meta);
405
+
406
+ for (const type of ["int64", "uint64"])
407
+ if (numbers.has(type) && bigints.has(type))
408
+ insert(
409
+ `tags.Type<"${type}"> cannot be used in both number and bigint types. Recommend to remove from number type`,
410
+ );
411
+ }
412
+ //----
413
+ // ARRRAY CASES
414
+ //----
415
+ // DO NOT ALLOW MULTI-DIMENTIONAL ARRAY
416
+ if (
417
+ meta.arrays.length &&
418
+ meta.arrays.some((array) => !!array.type.value.arrays.length)
114
419
  )
115
- )
116
- noSupport("optional type in array");
117
- // UNION IN ARRAY
118
- if (
119
- meta.arrays.length &&
120
- meta.arrays.some(
121
- (a) =>
122
- a.type.value.size() > 1 &&
123
- a.type.value.constants.length !== 1 &&
124
- a.type.value.constants[0]?.values.length !== a.type.value.size(),
420
+ noSupport("over two dimenstional array type");
421
+ // CHILD OF ARRAY TYPE MUST BE REQUIRED
422
+ if (
423
+ meta.arrays.length &&
424
+ meta.arrays.some(
425
+ (array) =>
426
+ array.type.value.isRequired() === false ||
427
+ array.type.value.nullable === true,
428
+ )
125
429
  )
126
- )
127
- noSupport("union type in array");
128
- // DO DYNAMIC OBJECT IN ARRAY
129
- if (
130
- meta.arrays.length &&
131
- meta.arrays.some(
132
- (a) =>
133
- a.type.value.maps.length ||
134
- (a.type.value.objects.length &&
135
- a.type.value.objects.some(
136
- (o) => ProtobufUtil.isStaticObject(o.type) === false,
137
- )),
430
+ noSupport("optional type in array");
431
+ // UNION IN ARRAY
432
+ if (
433
+ meta.arrays.length &&
434
+ meta.arrays.some(
435
+ (a) =>
436
+ a.type.value.size() > 1 &&
437
+ a.type.value.constants.length !== 1 &&
438
+ a.type.value.constants[0]?.values.length !== a.type.value.size(),
439
+ )
138
440
  )
139
- )
140
- noSupport("dynamic object in array");
141
- // UNION WITH ARRAY
142
- if (meta.size() > 1 && meta.arrays.length)
143
- noSupport("union type with array type");
144
- //----
145
- // OBJECT CASES
146
- //----
147
- // EMPTY PROPERTY
148
- if (
149
- meta.objects.length &&
150
- meta.objects.some((obj) => obj.type.properties.length === 0)
151
- )
152
- noSupport("empty object type");
153
- // MULTIPLE DYNAMIC KEY TYPED PROPERTIES
154
- if (
155
- meta.objects.length &&
156
- meta.objects.some(
157
- (obj) =>
158
- obj.type.properties.filter((p) => !p.key.isSoleLiteral()).length > 1,
441
+ noSupport("union type in array");
442
+ // DO DYNAMIC OBJECT IN ARRAY
443
+ if (
444
+ meta.arrays.length &&
445
+ meta.arrays.some(
446
+ (a) =>
447
+ a.type.value.maps.length ||
448
+ (a.type.value.objects.length &&
449
+ a.type.value.objects.some(
450
+ (o) => ProtobufUtil.isStaticObject(o.type) === false,
451
+ )),
452
+ )
159
453
  )
160
- )
161
- noSupport(
162
- "object type with multiple dynamic key typed properties. Keep only one.",
163
- );
164
- // STATIC AND DYNAMIC PROPERTIES ARE COMPATIBLE
165
- if (
166
- meta.objects.length &&
167
- meta.objects.some(
168
- (obj) =>
169
- obj.type.properties.some((p) => p.key.isSoleLiteral()) &&
170
- obj.type.properties.some((p) => !p.key.isSoleLiteral()),
454
+ noSupport("dynamic object in array");
455
+ // UNION WITH ARRAY
456
+ if (meta.size() > 1 && meta.arrays.length)
457
+ noSupport("union type with array type");
458
+ //----
459
+ // OBJECT CASES
460
+ //----
461
+ // EMPTY PROPERTY
462
+ if (
463
+ meta.objects.length &&
464
+ meta.objects.some((obj) => obj.type.properties.length === 0)
171
465
  )
172
- )
173
- noSupport(
174
- "object type with mixed static and dynamic key typed properties. Keep statics or dynamic only.",
175
- );
176
- // DYNAMIC OBJECT, BUT PROPERTY VALUE TYPE IS ARRAY
177
- if (
178
- meta.objects.length &&
179
- isDynamicObject(meta.objects[0]!.type) &&
180
- meta.objects[0]!.type.properties.some((p) => !!p.value.arrays.length)
181
- )
182
- noSupport("dynamic object with array value type");
183
- // UNION WITH DYNAMIC OBJECTa
184
- if (
185
- meta.size() > 1 &&
186
- meta.objects.length &&
187
- isDynamicObject(meta.objects[0]!.type)
188
- )
189
- noSupport("union type with dynamic object type");
190
- // UNION IN DYNAMIC PROPERTY VALUE
191
- if (
192
- meta.objects.length &&
193
- meta.objects.some(
194
- (obj) =>
195
- isDynamicObject(obj.type) &&
196
- obj.type.properties.some((p) => ProtobufUtil.isUnion(p.value)),
466
+ noSupport("empty object type");
467
+ // MULTIPLE DYNAMIC KEY TYPED PROPERTIES
468
+ if (
469
+ meta.objects.length &&
470
+ meta.objects.some(
471
+ (obj) =>
472
+ obj.type.properties.filter((p) => !p.key.isSoleLiteral()).length >
473
+ 1,
474
+ )
475
+ )
476
+ noSupport(
477
+ "object type with multiple dynamic key typed properties. Keep only one.",
478
+ );
479
+ // STATIC AND DYNAMIC PROPERTIES ARE COMPATIBLE
480
+ if (
481
+ meta.objects.length &&
482
+ meta.objects.some(
483
+ (obj) =>
484
+ obj.type.properties.some((p) => p.key.isSoleLiteral()) &&
485
+ obj.type.properties.some((p) => !p.key.isSoleLiteral()),
486
+ )
487
+ )
488
+ noSupport(
489
+ "object type with mixed static and dynamic key typed properties. Keep statics or dynamic only.",
490
+ );
491
+ // DYNAMIC OBJECT, BUT PROPERTY VALUE TYPE IS ARRAY
492
+ if (
493
+ meta.objects.length &&
494
+ isDynamicObject(meta.objects[0]!.type) &&
495
+ meta.objects[0]!.type.properties.some((p) => !!p.value.arrays.length)
496
+ )
497
+ noSupport("dynamic object with array value type");
498
+ // UNION WITH DYNAMIC OBJECTa
499
+ if (
500
+ meta.size() > 1 &&
501
+ meta.objects.length &&
502
+ isDynamicObject(meta.objects[0]!.type)
197
503
  )
198
- )
199
- noSupport("union type in dynamic property");
200
- //----
201
- // MAP CASES
202
- //----
203
- // KEY TYPE IS UNION
204
- if (meta.maps.length && meta.maps.some((m) => ProtobufUtil.isUnion(m.key)))
205
- noSupport("union key typed map");
206
- // KEY TYPE IS NOT ATOMIC
207
- if (
208
- meta.maps.length &&
209
- meta.maps.some((m) => ProtobufUtil.getAtomics(m.key).length !== 1)
210
- )
211
- noSupport("non-atomic key typed map");
212
- // MAP TYPE, BUT PROPERTY KEY TYPE IS OPTIONAL
213
- if (
214
- meta.maps.length &&
215
- meta.maps.some((m) => m.key.isRequired() === false || m.key.nullable)
216
- )
217
- noSupport("optional key typed map");
218
- // MAP TYPE, BUT VALUE TYPE IS ARRAY
219
- if (meta.maps.length && meta.maps.some((m) => !!m.value.arrays.length))
220
- noSupport("map type with array value type");
221
- // UNION WITH MAP
222
- if (meta.size() > 1 && meta.maps.length)
223
- noSupport("union type with map type");
224
- // UNION IN MAP
225
- if (
226
- meta.maps.length &&
227
- meta.maps.some((m) => ProtobufUtil.isUnion(m.value))
228
- )
229
- noSupport("union type in map value type");
230
- return errors;
504
+ noSupport("union type with dynamic object type");
505
+ // UNION IN DYNAMIC PROPERTY VALUE
506
+ if (
507
+ meta.objects.length &&
508
+ meta.objects.some(
509
+ (obj) =>
510
+ isDynamicObject(obj.type) &&
511
+ obj.type.properties.some((p) => ProtobufUtil.isUnion(p.value)),
512
+ )
513
+ )
514
+ noSupport("union type in dynamic property");
515
+ //----
516
+ // MAP CASES
517
+ //----
518
+ // KEY TYPE IS UNION
519
+ if (
520
+ meta.maps.length &&
521
+ meta.maps.some((m) => ProtobufUtil.isUnion(m.key))
522
+ )
523
+ noSupport("union key typed map");
524
+ // KEY TYPE IS NOT ATOMIC
525
+ if (
526
+ meta.maps.length &&
527
+ meta.maps.some((m) => ProtobufUtil.getAtomics(m.key).size !== 1)
528
+ )
529
+ noSupport("non-atomic key typed map");
530
+ // MAP TYPE, BUT PROPERTY KEY TYPE IS OPTIONAL
531
+ if (
532
+ meta.maps.length &&
533
+ meta.maps.some((m) => m.key.isRequired() === false || m.key.nullable)
534
+ )
535
+ noSupport("optional key typed map");
536
+ // MAP TYPE, BUT VALUE TYPE IS ARRAY
537
+ if (meta.maps.length && meta.maps.some((m) => !!m.value.arrays.length))
538
+ noSupport("map type with array value type");
539
+ // UNION WITH MAP
540
+ if (meta.size() > 1 && meta.maps.length)
541
+ noSupport("union type with map type");
542
+ // UNION IN MAP
543
+ if (
544
+ meta.maps.length &&
545
+ meta.maps.some((m) => ProtobufUtil.isUnion(m.value))
546
+ )
547
+ noSupport("union type in map value type");
548
+ return errors;
549
+ };
550
+ };
551
+
552
+ /* -----------------------------------------------------------
553
+ SEQUENE VALIDATOR
554
+ ----------------------------------------------------------- */
555
+ const validateObject = (next: {
556
+ object: MetadataObjectType;
557
+ errors: string[];
558
+ }): void => {
559
+ for (const property of next.object.properties)
560
+ validateProperty({
561
+ metadata: property.value,
562
+ errors: next.errors,
563
+ });
564
+
565
+ const entire: Map<number, string> = new Map();
566
+ const visitProperty = (p: MetadataProperty) => {
567
+ const local: Set<number> = new Set();
568
+ const tagger = (matrix: IMetadataTypeTag[][]): void => {
569
+ matrix.forEach((tags) => {
570
+ const value: number | null = ProtobufUtil.getSequence(tags);
571
+ if (value !== null) local.add(value);
572
+ });
573
+ };
574
+ for (const c of p.value.constants)
575
+ for (const v of c.values) tagger(v.tags);
576
+ for (const a of p.value.atomics) tagger(a.tags);
577
+ for (const t of p.value.templates) tagger(t.tags);
578
+ for (const o of p.value.objects) tagger(o.tags);
579
+ for (const a of p.value.arrays) tagger(a.tags);
580
+
581
+ for (const s of local)
582
+ if (entire.has(s))
583
+ next.errors.push(
584
+ `The Sequence<${s}> tag is duplicated in two properties (${JSON.stringify(entire.get(s))} and ${JSON.stringify(p.key.getSoleLiteral())})`,
585
+ );
586
+ else entire.set(s, p.key.getSoleLiteral()!);
587
+ };
588
+ for (const p of next.object.properties) visitProperty(p);
589
+ };
590
+
591
+ const validateProperty = (next: {
592
+ metadata: Metadata;
593
+ errors: string[];
594
+ }): void => {
595
+ let expected: number = 0;
596
+ const sequences: Set<number> = new Set();
597
+ const add = (value: number): boolean => {
598
+ if (sequences.has(value)) return false;
599
+ sequences.add(value);
600
+ ++expected;
601
+ return true;
602
+ };
603
+
604
+ for (const validator of [
605
+ validateBooleanSequence,
606
+ validateNumericSequences({
607
+ type: "bigint",
608
+ default: "int64",
609
+ categories: BIGINT_TYPES,
610
+ }),
611
+ validateNumericSequences({
612
+ type: "number",
613
+ default: "double",
614
+ categories: NUMBER_TYPES,
615
+ }),
616
+ validateStringSequence,
617
+ ])
618
+ validator({ metadata: next.metadata, errors: next.errors, add });
619
+ for (const array of next.metadata.arrays)
620
+ validateInstanceSequence({
621
+ type: "array",
622
+ tags: array.tags,
623
+ errors: next.errors,
624
+ add,
625
+ });
626
+ for (const object of next.metadata.objects)
627
+ validateInstanceSequence({
628
+ type: "object",
629
+ tags: object.tags,
630
+ errors: next.errors,
631
+ add,
632
+ });
633
+ for (const map of next.metadata.maps)
634
+ validateInstanceSequence({
635
+ type: "map",
636
+ tags: map.tags,
637
+ errors: next.errors,
638
+ add,
639
+ });
640
+ for (const native of next.metadata.natives)
641
+ if (native.name === "Uint8Array")
642
+ validateInstanceSequence({
643
+ type: "Uint8Array",
644
+ tags: native.tags,
645
+ errors: next.errors,
646
+ add,
647
+ });
648
+ };
649
+
650
+ const validateBooleanSequence = (next: {
651
+ metadata: Metadata;
652
+ errors: string[];
653
+ add: (value: number) => boolean;
654
+ }): void => {
655
+ // PREPARE EMPLACER
656
+ const unique: Set<number> = new Set();
657
+ let expected: number = 0;
658
+ let actual: number = 0;
659
+ const emplace = (matrix: IMetadataTypeTag[][]): void => {
660
+ for (const tags of matrix)
661
+ for (const tag of tags) {
662
+ const sequence = ProtobufUtil.getSequence([tag]);
663
+ if (sequence !== null) {
664
+ unique.add(sequence);
665
+ ++actual;
666
+ }
667
+ ++expected;
668
+ }
669
+ };
670
+
671
+ // GATHER SEQUENCE TAGS
672
+ for (const atomic of next.metadata.atomics)
673
+ if (atomic.type === "boolean") emplace(atomic.tags);
674
+ for (const constant of next.metadata.constants)
675
+ if (constant.type === "boolean")
676
+ for (const value of constant.values) emplace(value.tags);
677
+
678
+ // PREDICATE
679
+ if (unique.size && actual !== expected)
680
+ next.errors.push(
681
+ `The sequence tag must be declared in every union type members`,
682
+ );
683
+ else if (unique.size > 1)
684
+ next.errors.push(
685
+ `The sequence tag value must be the same in boolean type (including literal types)`,
686
+ );
687
+ else if (unique.size === 1) {
688
+ const value: number = unique.values().next().value!;
689
+ if (next.add(value) === false)
690
+ next.errors.push(
691
+ `The sequence tag value ${value} in boolean type is duplicated with other types`,
692
+ );
693
+ }
694
+ };
695
+
696
+ const validateNumericSequences =
697
+ (config: {
698
+ type: "number" | "bigint";
699
+ default: string;
700
+ categories: Set<string>;
701
+ }) =>
702
+ (next: {
703
+ metadata: Metadata;
704
+ errors: string[];
705
+ add: (value: number) => boolean;
706
+ }): void => {
707
+ // FIND TYPE CATEGORIES
708
+ const categories: Set<string> = new Set();
709
+ const getType = (tags: IMetadataTypeTag[]): string => {
710
+ const found: IMetadataTypeTag | undefined = tags.find(
711
+ (t) => t.kind === "type" && config.categories.has(t.value),
712
+ );
713
+ return found?.value ?? config.default;
714
+ };
715
+ const exploreCategory = (matrix: IMetadataTypeTag[][]): void => {
716
+ for (const tags of matrix) categories.add(getType(tags));
717
+ };
718
+ for (const atomic of next.metadata.atomics)
719
+ if (atomic.type === config.type) exploreCategory(atomic.tags);
720
+ for (const constant of next.metadata.constants)
721
+ if (constant.type === config.type)
722
+ for (const value of constant.values) exploreCategory(value.tags);
723
+
724
+ // ITERATE TYPE CATEGORIES
725
+ for (const category of categories) {
726
+ const unique: Set<number> = new Set();
727
+ let expected: number = 0;
728
+ let actual: number = 0;
729
+ const emplace = (tags: IMetadataTypeTag[]): void => {
730
+ const sequence: number | null = ProtobufUtil.getSequence(tags);
731
+ if (sequence !== null) {
732
+ unique.add(sequence);
733
+ ++actual;
734
+ }
735
+ ++expected;
736
+ };
737
+
738
+ for (const atomic of next.metadata.atomics)
739
+ if (atomic.type === config.type)
740
+ for (const tags of atomic.tags)
741
+ if (getType(tags) === category) emplace(tags);
742
+ for (const constant of next.metadata.constants)
743
+ if (constant.type === config.type)
744
+ for (const value of constant.values)
745
+ for (const tags of value.tags)
746
+ if (getType(tags) === category) emplace(tags);
747
+
748
+ if (unique.size && actual !== expected) {
749
+ console.log(category, actual, expected, unique);
750
+ next.errors.push(
751
+ `The sequence tag must be declared in every union type members`,
752
+ );
753
+ } else if (unique.size > 1)
754
+ next.errors.push(
755
+ `The sequence tag value must be the same in ${config.type} type (including literal types)`,
756
+ );
757
+ else if (unique.size === 1) {
758
+ const value: number = unique.values().next().value!;
759
+ if (next.add(value) === false)
760
+ next.errors.push(
761
+ `The sequence tag value ${value} in ${config.type} type is duplicated with other types`,
762
+ );
763
+ }
764
+ }
765
+ };
766
+
767
+ const validateStringSequence = (next: {
768
+ metadata: Metadata;
769
+ errors: string[];
770
+ add: (value: number) => boolean;
771
+ }): void => {
772
+ const unique: Set<number> = new Set();
773
+ let expected: number = 0;
774
+ let actual: number = 0;
775
+ const emplace = (matrix: IMetadataTypeTag[][]): void => {
776
+ for (const tags of matrix)
777
+ for (const tag of tags) {
778
+ const sequence = ProtobufUtil.getSequence([tag]);
779
+ if (sequence !== null) {
780
+ unique.add(sequence);
781
+ ++actual;
782
+ }
783
+ ++expected;
784
+ }
785
+ };
786
+ for (const atomic of next.metadata.atomics)
787
+ if (atomic.type === "string") emplace(atomic.tags);
788
+ for (const constant of next.metadata.constants)
789
+ if (constant.type === "string")
790
+ for (const value of constant.values) emplace(value.tags);
791
+ for (const template of next.metadata.templates) emplace(template.tags);
792
+
793
+ if (unique.size && actual !== expected)
794
+ next.errors.push(
795
+ `The sequence tag must be declared in every union type members`,
796
+ );
797
+ else if (unique.size > 1)
798
+ next.errors.push(
799
+ `The sequence tag value must be the same in string types including literal and template types`,
800
+ );
801
+ else if (unique.size === 1) {
802
+ const value: number = unique.values().next().value!;
803
+ if (next.add(value) === false)
804
+ next.errors.push(
805
+ `The sequence tag value ${value} in string type is duplicated with other types`,
806
+ );
807
+ }
808
+ };
809
+
810
+ const validateInstanceSequence = (next: {
811
+ type: "array" | "object" | "map" | "Uint8Array";
812
+ tags: IMetadataTypeTag[][];
813
+ errors: string[];
814
+ add: (value: number) => boolean;
815
+ }): void => {
816
+ const unique: Set<number> = new Set();
817
+ let count: number = 0;
818
+ for (const tags of next.tags) {
819
+ const value: number | null = ProtobufUtil.getSequence(tags);
820
+ if (value === null) continue;
821
+ unique.add(value);
822
+ ++count;
823
+ }
824
+ if (unique.size && count !== next.tags.length)
825
+ next.errors.push(
826
+ `The sequence tag must be declared in every union type members`,
827
+ );
828
+ else if (unique.size > 1)
829
+ next.errors.push(
830
+ `The sequence tag value must be the same in ${next.type === "array" ? "an array" : "object"} type.`,
831
+ );
832
+ else if (unique.size === 1) {
833
+ const value: number = unique.values().next().value!;
834
+ if (next.add(value) === false)
835
+ next.errors.push(
836
+ `The sequence tag value ${value} in ${next.type} type is duplicated with other types`,
837
+ );
838
+ }
231
839
  };
232
840
  }
233
841
 
@@ -259,3 +867,12 @@ const BANNED_NATIVE_TYPES: Map<string, string | null> = new Map([
259
867
  ["WeakSet", "Array"],
260
868
  ["WeakMap", "Map"],
261
869
  ]);
870
+ const NUMBER_TYPES: Set<string> = new Set([
871
+ "int32",
872
+ "uint32",
873
+ "int64",
874
+ "uint64",
875
+ "float",
876
+ "double",
877
+ ]);
878
+ const BIGINT_TYPES = new Set(["int64", "uint64"]);