typia 5.0.0-dev.20230823 → 5.0.0-dev.2023084

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 (217) hide show
  1. package/lib/Primitive.d.ts +14 -12
  2. package/lib/Resolved.d.ts +46 -0
  3. package/lib/{schemas/metadata/IMetadataResolved.js → Resolved.js} +1 -1
  4. package/lib/Resolved.js.map +1 -0
  5. package/lib/factories/MetadataFactory.d.ts +1 -1
  6. package/lib/factories/MetadataTagFactory.js +10 -8
  7. package/lib/factories/MetadataTagFactory.js.map +1 -1
  8. package/lib/factories/ProtobufFactory.js +4 -3
  9. package/lib/factories/ProtobufFactory.js.map +1 -1
  10. package/lib/factories/internal/metadata/emend_metadata_atomics.js +6 -6
  11. package/lib/factories/internal/metadata/emend_metadata_atomics.js.map +1 -1
  12. package/lib/factories/internal/metadata/explore_metadata.js +3 -3
  13. package/lib/factories/internal/metadata/explore_metadata.js.map +1 -1
  14. package/lib/factories/internal/metadata/iterate_metadata_atomic.js +1 -1
  15. package/lib/factories/internal/metadata/iterate_metadata_atomic.js.map +1 -1
  16. package/lib/factories/internal/metadata/iterate_metadata_collection.js +6 -6
  17. package/lib/factories/internal/metadata/iterate_metadata_collection.js.map +1 -1
  18. package/lib/factories/internal/metadata/iterate_metadata_native.js +2 -10
  19. package/lib/factories/internal/metadata/iterate_metadata_native.js.map +1 -1
  20. package/lib/factories/internal/metadata/iterate_metadata_resolve.js +6 -6
  21. package/lib/factories/internal/metadata/iterate_metadata_resolve.js.map +1 -1
  22. package/lib/factories/internal/metadata/iterate_metadata_sort.js +2 -2
  23. package/lib/factories/internal/metadata/iterate_metadata_sort.js.map +1 -1
  24. package/lib/functional/$ProtobufWriter.js.map +1 -1
  25. package/lib/json.d.ts +15 -15
  26. package/lib/misc.d.ts +42 -42
  27. package/lib/module.d.ts +18 -17
  28. package/lib/module.js +1 -0
  29. package/lib/module.js.map +1 -1
  30. package/lib/programmers/AssertProgrammer.js +1 -1
  31. package/lib/programmers/AssertProgrammer.js.map +1 -1
  32. package/lib/programmers/CheckerProgrammer.js +7 -7
  33. package/lib/programmers/CheckerProgrammer.js.map +1 -1
  34. package/lib/programmers/IsProgrammer.js +2 -2
  35. package/lib/programmers/IsProgrammer.js.map +1 -1
  36. package/lib/programmers/RandomProgrammer.js +311 -136
  37. package/lib/programmers/RandomProgrammer.js.map +1 -1
  38. package/lib/programmers/ValidateProgrammer.js +1 -1
  39. package/lib/programmers/ValidateProgrammer.js.map +1 -1
  40. package/lib/programmers/helpers/AtomicPredicator.js +2 -2
  41. package/lib/programmers/helpers/AtomicPredicator.js.map +1 -1
  42. package/lib/programmers/helpers/FunctionImporeter.d.ts +2 -0
  43. package/lib/programmers/helpers/FunctionImporeter.js +2 -1
  44. package/lib/programmers/helpers/FunctionImporeter.js.map +1 -1
  45. package/lib/programmers/helpers/ProtobufUtil.js +2 -2
  46. package/lib/programmers/helpers/ProtobufUtil.js.map +1 -1
  47. package/lib/programmers/helpers/StringifyPredicator.js +1 -2
  48. package/lib/programmers/helpers/StringifyPredicator.js.map +1 -1
  49. package/lib/programmers/helpers/disable_function_importer_declare.js +1 -0
  50. package/lib/programmers/helpers/disable_function_importer_declare.js.map +1 -1
  51. package/lib/programmers/internal/application_default_string.js +2 -2
  52. package/lib/programmers/internal/application_default_string.js.map +1 -1
  53. package/lib/programmers/internal/application_resolved.d.ts +2 -2
  54. package/lib/programmers/internal/application_resolved.js.map +1 -1
  55. package/lib/programmers/internal/application_schema.js +7 -7
  56. package/lib/programmers/internal/application_schema.js.map +1 -1
  57. package/lib/programmers/internal/metadata_to_pattern.js +4 -4
  58. package/lib/programmers/internal/metadata_to_pattern.js.map +1 -1
  59. package/lib/programmers/internal/stringify_dynamic_properties.js +2 -1
  60. package/lib/programmers/internal/stringify_dynamic_properties.js.map +1 -1
  61. package/lib/programmers/json/JsonStringifyProgrammer.js +20 -14
  62. package/lib/programmers/json/JsonStringifyProgrammer.js.map +1 -1
  63. package/lib/programmers/misc/MiscAssertCloneProgrammer.js +1 -1
  64. package/lib/programmers/misc/MiscAssertCloneProgrammer.js.map +1 -1
  65. package/lib/programmers/misc/MiscCloneProgrammer.js +114 -33
  66. package/lib/programmers/misc/MiscCloneProgrammer.js.map +1 -1
  67. package/lib/programmers/misc/MiscIsCloneProgrammer.js +1 -1
  68. package/lib/programmers/misc/MiscIsCloneProgrammer.js.map +1 -1
  69. package/lib/programmers/misc/MiscLiteralsProgrammer.js +3 -3
  70. package/lib/programmers/misc/MiscLiteralsProgrammer.js.map +1 -1
  71. package/lib/programmers/misc/MiscPruneProgrammer.js +2 -2
  72. package/lib/programmers/misc/MiscPruneProgrammer.js.map +1 -1
  73. package/lib/programmers/misc/MiscValidateCloneProgrammer.js +1 -1
  74. package/lib/programmers/misc/MiscValidateCloneProgrammer.js.map +1 -1
  75. package/lib/programmers/protobuf/ProtobufAssertDecodeProgrammer.js +3 -3
  76. package/lib/programmers/protobuf/ProtobufAssertDecodeProgrammer.js.map +1 -1
  77. package/lib/programmers/protobuf/ProtobufDecodeProgrammer.js +3 -3
  78. package/lib/programmers/protobuf/ProtobufDecodeProgrammer.js.map +1 -1
  79. package/lib/programmers/protobuf/ProtobufEncodeProgrammer.js +1 -1
  80. package/lib/programmers/protobuf/ProtobufEncodeProgrammer.js.map +1 -1
  81. package/lib/programmers/protobuf/ProtobufIsDecodeProgrammer.js +2 -2
  82. package/lib/programmers/protobuf/ProtobufIsDecodeProgrammer.js.map +1 -1
  83. package/lib/programmers/protobuf/ProtobufValidateDecodeProgrammer.js +1 -1
  84. package/lib/programmers/protobuf/ProtobufValidateDecodeProgrammer.js.map +1 -1
  85. package/lib/protobuf.d.ts +631 -10
  86. package/lib/protobuf.js +13 -13
  87. package/lib/protobuf.js.map +1 -1
  88. package/lib/schemas/metadata/IMetadata.d.ts +4 -4
  89. package/lib/schemas/metadata/IMetadataAtomic.d.ts +12 -0
  90. package/lib/schemas/metadata/IMetadataAtomic.js +3 -0
  91. package/lib/schemas/metadata/IMetadataAtomic.js.map +1 -0
  92. package/lib/schemas/metadata/{IMetadataResolved.d.ts → IMetadataEscaped.d.ts} +1 -1
  93. package/lib/schemas/metadata/IMetadataEscaped.js +3 -0
  94. package/lib/schemas/metadata/IMetadataEscaped.js.map +1 -0
  95. package/lib/schemas/metadata/Metadata.d.ts +4 -4
  96. package/lib/schemas/metadata/Metadata.js +64 -59
  97. package/lib/schemas/metadata/Metadata.js.map +1 -1
  98. package/lib/schemas/metadata/{MetadataResolved.d.ts → MetadataEscaped.d.ts} +3 -3
  99. package/lib/schemas/metadata/{MetadataResolved.js → MetadataEscaped.js} +11 -11
  100. package/lib/schemas/metadata/MetadataEscaped.js.map +1 -0
  101. package/lib/tags/ExclusiveMaximum.d.ts +8 -0
  102. package/lib/tags/ExclusiveMaximum.js +3 -0
  103. package/lib/tags/ExclusiveMaximum.js.map +1 -0
  104. package/lib/tags/ExclusiveMinimum.d.ts +8 -0
  105. package/lib/tags/ExclusiveMinimum.js +3 -0
  106. package/lib/tags/ExclusiveMinimum.js.map +1 -0
  107. package/lib/tags/Format.d.ts +8 -0
  108. package/lib/tags/Format.js +3 -0
  109. package/lib/tags/Format.js.map +1 -0
  110. package/lib/tags/MaxItems.d.ts +8 -0
  111. package/lib/tags/MaxItems.js +3 -0
  112. package/lib/tags/MaxItems.js.map +1 -0
  113. package/lib/tags/MaxLength.d.ts +8 -0
  114. package/lib/tags/MaxLength.js +3 -0
  115. package/lib/tags/MaxLength.js.map +1 -0
  116. package/lib/tags/Maximum.d.ts +8 -0
  117. package/lib/tags/Maximum.js +3 -0
  118. package/lib/tags/Maximum.js.map +1 -0
  119. package/lib/tags/MinItems.d.ts +8 -0
  120. package/lib/tags/MinItems.js +3 -0
  121. package/lib/tags/MinItems.js.map +1 -0
  122. package/lib/tags/MinLength.d.ts +8 -0
  123. package/lib/tags/MinLength.js +3 -0
  124. package/lib/tags/MinLength.js.map +1 -0
  125. package/lib/tags/Minimum.d.ts +8 -0
  126. package/lib/tags/Minimum.js +3 -0
  127. package/lib/tags/Minimum.js.map +1 -0
  128. package/lib/tags/MultipleOf.d.ts +8 -0
  129. package/lib/tags/MultipleOf.js +3 -0
  130. package/lib/tags/MultipleOf.js.map +1 -0
  131. package/lib/tags/Pattern.d.ts +8 -0
  132. package/lib/tags/Pattern.js +3 -0
  133. package/lib/tags/Pattern.js.map +1 -0
  134. package/lib/tags/TagBase.d.ts +10 -0
  135. package/lib/tags/TagBase.js +3 -0
  136. package/lib/tags/TagBase.js.map +1 -0
  137. package/lib/tags/Type.d.ts +13 -0
  138. package/lib/tags/Type.js +3 -0
  139. package/lib/tags/Type.js.map +1 -0
  140. package/lib/tags/index.d.ts +12 -0
  141. package/lib/tags/index.js +29 -0
  142. package/lib/tags/index.js.map +1 -0
  143. package/lib/transformers/features/json/JsonApplicationTransformer.js +2 -2
  144. package/lib/transformers/features/json/JsonApplicationTransformer.js.map +1 -1
  145. package/lib/transformers/features/misc/MetadataTransformer.js +1 -1
  146. package/lib/transformers/features/misc/MetadataTransformer.js.map +1 -1
  147. package/lib/utils/RandomGenerator.js +3 -2
  148. package/lib/utils/RandomGenerator.js.map +1 -1
  149. package/package.json +2 -1
  150. package/src/Primitive.ts +135 -131
  151. package/src/Resolved.ts +116 -0
  152. package/src/factories/MetadataFactory.ts +46 -46
  153. package/src/factories/MetadataTagFactory.ts +366 -364
  154. package/src/factories/ProtobufFactory.ts +268 -266
  155. package/src/factories/internal/metadata/emend_metadata_atomics.ts +35 -33
  156. package/src/factories/internal/metadata/explore_metadata.ts +38 -38
  157. package/src/factories/internal/metadata/iterate_metadata_atomic.ts +63 -59
  158. package/src/factories/internal/metadata/iterate_metadata_collection.ts +133 -133
  159. package/src/factories/internal/metadata/iterate_metadata_native.ts +210 -219
  160. package/src/factories/internal/metadata/iterate_metadata_resolve.ts +49 -49
  161. package/src/factories/internal/metadata/iterate_metadata_sort.ts +69 -69
  162. package/src/functional/$ProtobufWriter.ts +151 -151
  163. package/src/json.ts +648 -648
  164. package/src/misc.ts +651 -651
  165. package/src/module.ts +709 -708
  166. package/src/programmers/AssertProgrammer.ts +281 -279
  167. package/src/programmers/CheckerProgrammer.ts +1174 -1173
  168. package/src/programmers/IsProgrammer.ts +241 -239
  169. package/src/programmers/RandomProgrammer.ts +874 -578
  170. package/src/programmers/ValidateProgrammer.ts +307 -305
  171. package/src/programmers/helpers/AtomicPredicator.ts +31 -31
  172. package/src/programmers/helpers/FunctionImporeter.ts +91 -89
  173. package/src/programmers/helpers/ProtobufUtil.ts +29 -29
  174. package/src/programmers/helpers/StringifyPredicator.ts +12 -13
  175. package/src/programmers/helpers/disable_function_importer_declare.ts +32 -27
  176. package/src/programmers/internal/application_default_string.ts +37 -33
  177. package/src/programmers/internal/application_resolved.ts +55 -55
  178. package/src/programmers/internal/application_schema.ts +157 -157
  179. package/src/programmers/internal/metadata_to_pattern.ts +34 -34
  180. package/src/programmers/internal/stringify_dynamic_properties.ts +171 -171
  181. package/src/programmers/json/JsonStringifyProgrammer.ts +995 -987
  182. package/src/programmers/misc/MiscAssertCloneProgrammer.ts +71 -71
  183. package/src/programmers/misc/MiscCloneProgrammer.ts +775 -587
  184. package/src/programmers/misc/MiscIsCloneProgrammer.ts +78 -78
  185. package/src/programmers/misc/MiscLiteralsProgrammer.ts +64 -64
  186. package/src/programmers/misc/MiscPruneProgrammer.ts +544 -542
  187. package/src/programmers/misc/MiscValidateCloneProgrammer.ts +85 -85
  188. package/src/programmers/protobuf/ProtobufAssertDecodeProgrammer.ts +75 -66
  189. package/src/programmers/protobuf/ProtobufDecodeProgrammer.ts +673 -669
  190. package/src/programmers/protobuf/ProtobufEncodeProgrammer.ts +814 -814
  191. package/src/programmers/protobuf/ProtobufIsDecodeProgrammer.ts +85 -75
  192. package/src/programmers/protobuf/ProtobufValidateDecodeProgrammer.ts +75 -75
  193. package/src/protobuf.ts +881 -249
  194. package/src/schemas/metadata/IMetadata.ts +27 -28
  195. package/src/schemas/metadata/IMetadataAtomic.ts +13 -0
  196. package/src/schemas/metadata/{IMetadataResolved.ts → IMetadataEscaped.ts} +6 -6
  197. package/src/schemas/metadata/Metadata.ts +643 -637
  198. package/src/schemas/metadata/{MetadataResolved.ts → MetadataEscaped.ts} +51 -51
  199. package/src/tags/ExclusiveMaximum.ts +8 -0
  200. package/src/tags/ExclusiveMinimum.ts +8 -0
  201. package/src/tags/Format.ts +29 -0
  202. package/src/tags/MaxItems.ts +8 -0
  203. package/src/tags/MaxLength.ts +8 -0
  204. package/src/tags/Maximum.ts +8 -0
  205. package/src/tags/MinItems.ts +8 -0
  206. package/src/tags/MinLength.ts +8 -0
  207. package/src/tags/Minimum.ts +8 -0
  208. package/src/tags/MultipleOf.ts +10 -0
  209. package/src/tags/Pattern.ts +8 -0
  210. package/src/tags/TagBase.ts +17 -0
  211. package/src/tags/Type.ts +30 -0
  212. package/src/tags/index.ts +12 -0
  213. package/src/transformers/features/json/JsonApplicationTransformer.ts +111 -111
  214. package/src/transformers/features/misc/MetadataTransformer.ts +53 -53
  215. package/src/utils/RandomGenerator.ts +83 -81
  216. package/lib/schemas/metadata/IMetadataResolved.js.map +0 -1
  217. package/lib/schemas/metadata/MetadataResolved.js.map +0 -1
@@ -1,669 +1,673 @@
1
- import ts from "typescript";
2
-
3
- import { ExpressionFactory } from "../../factories/ExpressionFactory";
4
- import { IdentifierFactory } from "../../factories/IdentifierFactory";
5
- import { MetadataCollection } from "../../factories/MetadataCollection";
6
- import { MetadataFactory } from "../../factories/MetadataFactory";
7
- import { ProtobufFactory } from "../../factories/ProtobufFactory";
8
- import { StatementFactory } from "../../factories/StatementFactory";
9
- import { TypeFactory } from "../../factories/TypeFactory";
10
-
11
- import { IMetadataTag } from "../../schemas/metadata/IMetadataTag";
12
- import { Metadata } from "../../schemas/metadata/Metadata";
13
- import { MetadataArray } from "../../schemas/metadata/MetadataArray";
14
- import { MetadataObject } from "../../schemas/metadata/MetadataObject";
15
- import { MetadataProperty } from "../../schemas/metadata/MetadataProperty";
16
-
17
- import { IProject } from "../../transformers/IProject";
18
-
19
- import { Atomic } from "../../typings/Atomic";
20
-
21
- import { FunctionImporter } from "../helpers/FunctionImporeter";
22
- import { ProtobufUtil } from "../helpers/ProtobufUtil";
23
-
24
- export namespace ProtobufDecodeProgrammer {
25
- export const write =
26
- (project: IProject) =>
27
- (modulo: ts.LeftHandSideExpression) =>
28
- (type: ts.Type, name?: string): ts.ArrowFunction => {
29
- const importer: FunctionImporter = new FunctionImporter();
30
- const collection: MetadataCollection = new MetadataCollection();
31
- const meta: Metadata = ProtobufFactory.metadata(modulo.getText())(
32
- project.checker,
33
- )(collection)(type);
34
-
35
- const functors = collection
36
- .objects()
37
- .filter((obj) => ProtobufUtil.isStaticObject(obj))
38
- .map((obj) =>
39
- StatementFactory.constant(
40
- `${PREFIX}o${obj.index}`,
41
- write_object_function(project)(importer)(obj),
42
- ),
43
- );
44
- const reader = StatementFactory.constant(
45
- "reader",
46
- ts.factory.createNewExpression(
47
- importer.use("Reader"),
48
- undefined,
49
- [ts.factory.createIdentifier("input")],
50
- ),
51
- );
52
-
53
- return ts.factory.createArrowFunction(
54
- undefined,
55
- undefined,
56
- [
57
- IdentifierFactory.parameter(
58
- "input",
59
- ts.factory.createTypeReferenceNode("Uint8Array"),
60
- ),
61
- ],
62
- ts.factory.createTypeReferenceNode(
63
- name ?? TypeFactory.getFullName(project.checker)(type),
64
- ),
65
- undefined,
66
- ts.factory.createBlock(
67
- [
68
- ...importer.declare(modulo),
69
- ...functors,
70
- reader,
71
- ts.factory.createReturnStatement(
72
- decode_regular_object(true)(meta.objects[0]!),
73
- ),
74
- ],
75
- true,
76
- ),
77
- );
78
- };
79
-
80
- const write_object_function =
81
- (project: IProject) =>
82
- (importer: FunctionImporter) =>
83
- (obj: MetadataObject): ts.ArrowFunction =>
84
- ts.factory.createArrowFunction(
85
- undefined,
86
- undefined,
87
- [
88
- IdentifierFactory.parameter("reader"),
89
- IdentifierFactory.parameter(
90
- "length",
91
- TypeFactory.keyword("number"),
92
- ts.factory.createNumericLiteral(-1),
93
- ),
94
- ],
95
- TypeFactory.keyword("any"),
96
- undefined,
97
- ts.factory.createBlock(
98
- [
99
- ts.factory.createExpressionStatement(
100
- ts.factory.createBinaryExpression(
101
- ts.factory.createIdentifier("length"),
102
- ts.factory.createToken(
103
- ts.SyntaxKind.EqualsToken,
104
- ),
105
- ts.factory.createConditionalExpression(
106
- ts.factory.createLessThan(
107
- ts.factory.createIdentifier("length"),
108
- ts.factory.createNumericLiteral(0),
109
- ),
110
- undefined,
111
- ts.factory.createCallExpression(
112
- IdentifierFactory.access(READER())(
113
- "size",
114
- ),
115
- undefined,
116
- undefined,
117
- ),
118
- undefined,
119
- ts.factory.createAdd(
120
- ts.factory.createCallExpression(
121
- IdentifierFactory.access(READER())(
122
- "index",
123
- ),
124
- undefined,
125
- undefined,
126
- ),
127
- ts.factory.createIdentifier("length"),
128
- ),
129
- ),
130
- ),
131
- ),
132
- ...write_object_function_body(project)(importer)({
133
- condition: ts.factory.createLessThan(
134
- ts.factory.createCallExpression(
135
- IdentifierFactory.access(READER())("index"),
136
- undefined,
137
- undefined,
138
- ),
139
- ts.factory.createIdentifier("length"),
140
- ),
141
- tag: "tag",
142
- output: "output",
143
- })(obj.properties),
144
- ts.factory.createReturnStatement(
145
- ts.factory.createIdentifier("output"),
146
- ),
147
- ],
148
- true,
149
- ),
150
- );
151
-
152
- const write_object_function_body =
153
- (project: IProject) =>
154
- (importer: FunctionImporter) =>
155
- (props: { condition: ts.Expression; tag: string; output: string }) =>
156
- (properties: MetadataProperty[]): ts.Statement[] => {
157
- let i: number = 1;
158
- const clauses: ts.CaseClause[] = properties
159
- .map((p) => {
160
- const clause = decode_property(project)(importer)(i)(
161
- IdentifierFactory.access(
162
- ts.factory.createIdentifier(props.output),
163
- )(p.key.getSoleLiteral()!),
164
- p.value,
165
- p.tags,
166
- );
167
- i += p.value.binarySize();
168
- return clause;
169
- })
170
- .flat();
171
- return [
172
- StatementFactory.constant(
173
- props.output,
174
- ts.factory.createObjectLiteralExpression(
175
- properties.map((p) =>
176
- ts.factory.createPropertyAssignment(
177
- IdentifierFactory.identifier(
178
- p.key.getSoleLiteral()!,
179
- ),
180
- write_property_default_value(p.value),
181
- ),
182
- ),
183
- true,
184
- ),
185
- ),
186
- ts.factory.createWhileStatement(
187
- props.condition,
188
- ts.factory.createBlock([
189
- StatementFactory.constant(
190
- props.tag,
191
- ts.factory.createCallExpression(
192
- IdentifierFactory.access(READER())("uint32"),
193
- undefined,
194
- undefined,
195
- ),
196
- ),
197
- ts.factory.createSwitchStatement(
198
- ts.factory.createUnsignedRightShift(
199
- ts.factory.createIdentifier(props.tag),
200
- ts.factory.createNumericLiteral(3),
201
- ),
202
- ts.factory.createCaseBlock([
203
- ...clauses,
204
- ts.factory.createDefaultClause([
205
- ts.factory.createExpressionStatement(
206
- ts.factory.createCallExpression(
207
- IdentifierFactory.access(READER())(
208
- "skipType",
209
- ),
210
- undefined,
211
- [
212
- ts.factory.createBitwiseAnd(
213
- ts.factory.createIdentifier(
214
- props.tag,
215
- ),
216
- ts.factory.createNumericLiteral(
217
- 7,
218
- ),
219
- ),
220
- ],
221
- ),
222
- ),
223
- ts.factory.createBreakStatement(),
224
- ]),
225
- ]),
226
- ),
227
- ]),
228
- ),
229
- ];
230
- };
231
-
232
- const write_property_default_value = (value: Metadata) =>
233
- ts.factory.createAsExpression(
234
- value.nullable
235
- ? ts.factory.createNull()
236
- : value.isRequired() === false
237
- ? ts.factory.createIdentifier("undefined")
238
- : value.arrays.length
239
- ? ts.factory.createArrayLiteralExpression()
240
- : value.maps.length
241
- ? ts.factory.createNewExpression(
242
- ts.factory.createIdentifier("Map"),
243
- undefined,
244
- [],
245
- )
246
- : value.natives.length
247
- ? ts.factory.createNewExpression(
248
- ts.factory.createIdentifier("Uint8Array"),
249
- undefined,
250
- [],
251
- )
252
- : value.atomics.some((str) => str === "string") ||
253
- value.constants.some(
254
- (c) =>
255
- c.type === "string" && c.values.some((v) => v === ""),
256
- ) ||
257
- value.templates.some(
258
- (tpl) =>
259
- tpl.length === 1 && tpl[0]!.getName() === "string",
260
- )
261
- ? ts.factory.createStringLiteral("")
262
- : value.objects.length &&
263
- value.objects.some((obj) => !ProtobufUtil.isStaticObject(obj))
264
- ? ts.factory.createObjectLiteralExpression()
265
- : ts.factory.createIdentifier("undefined"),
266
- TypeFactory.keyword("any"),
267
- );
268
-
269
- /* -----------------------------------------------------------
270
- DECODERS
271
- ----------------------------------------------------------- */
272
- const decode_property =
273
- (project: IProject) =>
274
- (importer: FunctionImporter) =>
275
- (index: number) =>
276
- (
277
- accessor: ts.ElementAccessExpression | ts.PropertyAccessExpression,
278
- meta: Metadata,
279
- tags: IMetadataTag[],
280
- ): ts.CaseClause[] => {
281
- const clauses: ts.CaseClause[] = [];
282
- const emplace =
283
- (name: string) => (v: ts.Expression | ts.Statement[]) =>
284
- clauses.push(
285
- ts.factory.createCaseClause(
286
- ts.factory.createNumericLiteral(index++),
287
- Array.isArray(v)
288
- ? [
289
- ts.factory.createExpressionStatement(
290
- ts.factory.createIdentifier(
291
- `// type: ${name}`,
292
- ),
293
- ),
294
- ...v,
295
- ts.factory.createBreakStatement(),
296
- ]
297
- : [
298
- ts.factory.createExpressionStatement(
299
- ts.factory.createIdentifier(
300
- `// ${name}`,
301
- ),
302
- ),
303
- ts.factory.createExpressionStatement(
304
- ts.factory.createBinaryExpression(
305
- accessor,
306
- ts.factory.createToken(
307
- ts.SyntaxKind.EqualsToken,
308
- ),
309
- v,
310
- ),
311
- ),
312
- ts.factory.createBreakStatement(),
313
- ],
314
- ),
315
- );
316
-
317
- const required: boolean = meta.isRequired() && !meta.nullable;
318
- for (const atomic of ProtobufUtil.getAtomics(meta))
319
- emplace(atomic)(decode_atomic(atomic, tags));
320
- if (meta.natives.length) emplace("bytes")(decode_bytes("bytes"));
321
- for (const array of meta.arrays)
322
- emplace(`Array<${array.value.getName()}>`)(
323
- decode_array(accessor, array, required, tags),
324
- );
325
- for (const map of meta.maps)
326
- emplace(`Map<string, ${map.value.getName()}>`)(
327
- decode_map(project)(importer)(
328
- accessor,
329
- map,
330
- required,
331
- tags,
332
- ),
333
- );
334
- for (const obj of meta.objects)
335
- emplace(obj.name)(
336
- ProtobufUtil.isStaticObject(obj)
337
- ? decode_regular_object(false)(obj)
338
- : decode_dynamic_object(project)(importer)(
339
- accessor,
340
- obj,
341
- required,
342
- ),
343
- );
344
- return clauses;
345
- };
346
-
347
- const decode_atomic = (
348
- atomic: Atomic.Literal,
349
- tags: IMetadataTag[],
350
- ): ts.Expression => {
351
- if (atomic === "string") return decode_bytes("string");
352
- const method =
353
- atomic === "bigint"
354
- ? tags.find((t) => t.kind === "type" && t.value === "uint64")
355
- ? "uint64"
356
- : "int64"
357
- : atomic === "number"
358
- ? (() => {
359
- const type = tags.find((t) => t.kind === "type");
360
- if (type === undefined) return "double";
361
- return type.value === "int" || type.value === "int32"
362
- ? "int32"
363
- : type.value === "uint" || type.value === "uint32"
364
- ? "uint32"
365
- : type.value === "int64"
366
- ? "int64"
367
- : type.value === "uint64"
368
- ? "uint64"
369
- : type.value === "float"
370
- ? "float"
371
- : "double";
372
- })()
373
- : "bool";
374
- const call = ts.factory.createCallExpression(
375
- IdentifierFactory.access(ts.factory.createIdentifier("reader"))(
376
- method,
377
- ),
378
- undefined,
379
- undefined,
380
- );
381
- return atomic === "number" &&
382
- (method === "int64" || method === "uint64")
383
- ? ts.factory.createCallExpression(
384
- ts.factory.createIdentifier("Number"),
385
- undefined,
386
- [call],
387
- )
388
- : call;
389
- };
390
-
391
- const decode_bytes = (method: "bytes" | "string"): ts.Expression =>
392
- ts.factory.createCallExpression(
393
- IdentifierFactory.access(ts.factory.createIdentifier("reader"))(
394
- method,
395
- ),
396
- undefined,
397
- undefined,
398
- );
399
-
400
- const decode_array = (
401
- accessor: ts.ElementAccessExpression | ts.PropertyAccessExpression,
402
- array: MetadataArray,
403
- required: boolean,
404
- tags: IMetadataTag[],
405
- ): ts.Statement[] => {
406
- const statements: Array<ts.Expression | ts.Statement> = [];
407
- if (required === false)
408
- statements.push(
409
- ts.factory.createBinaryExpression(
410
- accessor,
411
- ts.factory.createToken(
412
- ts.SyntaxKind.QuestionQuestionEqualsToken,
413
- ),
414
- ts.factory.createAsExpression(
415
- ts.factory.createArrayLiteralExpression(),
416
- ts.factory.createTypeReferenceNode("any[]"),
417
- ),
418
- ),
419
- );
420
- const atomics = ProtobufUtil.getAtomics(array.value);
421
- const decoder = atomics.length
422
- ? () => decode_atomic(atomics[0]!, tags)
423
- : array.value.natives.length
424
- ? () => decode_bytes("bytes")
425
- : array.value.objects.length
426
- ? () => decode_regular_object(false)(array.value.objects[0]!)
427
- : null;
428
- if (decoder === null) throw new Error("Never reach here.");
429
- else if (atomics.length && atomics[0] !== "string") {
430
- statements.push(
431
- ts.factory.createIfStatement(
432
- ts.factory.createStrictEquality(
433
- ts.factory.createNumericLiteral(2),
434
- ts.factory.createBitwiseAnd(
435
- ts.factory.createIdentifier("tag"),
436
- ts.factory.createNumericLiteral(7),
437
- ),
438
- ),
439
- ts.factory.createBlock(
440
- [
441
- StatementFactory.constant(
442
- "piece",
443
- ts.factory.createAdd(
444
- ts.factory.createCallExpression(
445
- IdentifierFactory.access(READER())(
446
- "uint32",
447
- ),
448
- undefined,
449
- undefined,
450
- ),
451
- ts.factory.createCallExpression(
452
- IdentifierFactory.access(READER())(
453
- "index",
454
- ),
455
- undefined,
456
- undefined,
457
- ),
458
- ),
459
- ),
460
- ts.factory.createWhileStatement(
461
- ts.factory.createLessThan(
462
- ts.factory.createCallExpression(
463
- IdentifierFactory.access(READER())(
464
- "index",
465
- ),
466
- undefined,
467
- undefined,
468
- ),
469
- ts.factory.createIdentifier("piece"),
470
- ),
471
- ts.factory.createExpressionStatement(
472
- ts.factory.createCallExpression(
473
- IdentifierFactory.access(accessor)(
474
- "push",
475
- ),
476
- undefined,
477
- [decoder()],
478
- ),
479
- ),
480
- ),
481
- ],
482
- true,
483
- ),
484
- ts.factory.createExpressionStatement(
485
- ts.factory.createCallExpression(
486
- IdentifierFactory.access(accessor)("push"),
487
- undefined,
488
- [decoder()],
489
- ),
490
- ),
491
- ),
492
- );
493
- } else
494
- statements.push(
495
- ts.factory.createCallExpression(
496
- IdentifierFactory.access(accessor)("push"),
497
- undefined,
498
- [decoder()],
499
- ),
500
- );
501
- return statements.map((stmt) =>
502
- ts.isExpression(stmt)
503
- ? ts.factory.createExpressionStatement(stmt)
504
- : stmt,
505
- );
506
- };
507
-
508
- const decode_regular_object =
509
- (top: boolean) =>
510
- (obj: MetadataObject): ts.Expression =>
511
- ts.factory.createCallExpression(
512
- ts.factory.createIdentifier(`${PREFIX}o${obj.index}`),
513
- undefined,
514
- [
515
- ts.factory.createIdentifier("reader"),
516
- ...(top
517
- ? []
518
- : [
519
- ts.factory.createCallExpression(
520
- IdentifierFactory.access(READER())("uint32"),
521
- undefined,
522
- undefined,
523
- ),
524
- ]),
525
- ],
526
- );
527
-
528
- const decode_dynamic_object =
529
- (project: IProject) =>
530
- (importer: FunctionImporter) =>
531
- (
532
- accessor: ts.ElementAccessExpression | ts.PropertyAccessExpression,
533
- obj: MetadataObject,
534
- required: boolean,
535
- ): ts.Statement[] => {
536
- const top = obj.properties[0]!;
537
- return decode_entry(project)(importer)({
538
- initializer: () =>
539
- ts.factory.createBinaryExpression(
540
- accessor,
541
- ts.factory.createToken(
542
- ts.SyntaxKind.QuestionQuestionEqualsToken,
543
- ),
544
- ts.factory.createObjectLiteralExpression(),
545
- ),
546
- setter: () =>
547
- ts.factory.createBinaryExpression(
548
- ts.factory.createElementAccessExpression(
549
- accessor,
550
- ts.factory.createIdentifier("entry.key"),
551
- ),
552
- ts.factory.createToken(ts.SyntaxKind.EqualsToken),
553
- ts.factory.createIdentifier("entry.value"),
554
- ),
555
- })(top, required, top.tags);
556
- };
557
-
558
- const decode_map =
559
- (project: IProject) =>
560
- (importer: FunctionImporter) =>
561
- (
562
- accessor: ts.ElementAccessExpression | ts.PropertyAccessExpression,
563
- map: Metadata.Entry,
564
- required: boolean,
565
- tags: IMetadataTag[],
566
- ): ts.Statement[] =>
567
- decode_entry(project)(importer)({
568
- initializer: () =>
569
- ts.factory.createBinaryExpression(
570
- accessor,
571
- ts.factory.createToken(
572
- ts.SyntaxKind.QuestionQuestionEqualsToken,
573
- ),
574
- ts.factory.createNewExpression(
575
- ts.factory.createIdentifier("Map"),
576
- [
577
- TypeFactory.keyword("any"),
578
- TypeFactory.keyword("any"),
579
- ],
580
- [],
581
- ),
582
- ),
583
- setter: () =>
584
- ts.factory.createCallExpression(
585
- IdentifierFactory.access(accessor)("set"),
586
- undefined,
587
- [
588
- ts.factory.createIdentifier("entry.key"),
589
- ts.factory.createIdentifier("entry.value"),
590
- ],
591
- ),
592
- })(map, required, tags);
593
-
594
- const decode_entry =
595
- (project: IProject) =>
596
- (importer: FunctionImporter) =>
597
- (props: {
598
- initializer: () => ts.Expression;
599
- setter: () => ts.Expression;
600
- }) =>
601
- (
602
- map: Metadata.Entry,
603
- required: boolean,
604
- tags: IMetadataTag[],
605
- ): ts.Statement[] => {
606
- const statements: ts.Statement[] = [
607
- ...(required
608
- ? []
609
- : [
610
- ts.factory.createExpressionStatement(
611
- props.initializer(),
612
- ),
613
- ]),
614
- StatementFactory.constant(
615
- "piece",
616
- ts.factory.createAdd(
617
- ts.factory.createCallExpression(
618
- IdentifierFactory.access(READER())("uint32"),
619
- undefined,
620
- undefined,
621
- ),
622
- ts.factory.createCallExpression(
623
- IdentifierFactory.access(READER())("index"),
624
- undefined,
625
- undefined,
626
- ),
627
- ),
628
- ),
629
- ...write_object_function_body(project)(importer)({
630
- condition: ts.factory.createLessThan(
631
- ts.factory.createCallExpression(
632
- IdentifierFactory.access(READER())("index"),
633
- undefined,
634
- undefined,
635
- ),
636
- ts.factory.createIdentifier("piece"),
637
- ),
638
- tag: "kind",
639
- output: "entry",
640
- })([
641
- MetadataProperty.create({
642
- key: MetadataFactory.soleLiteral("key"),
643
- value: map.key,
644
- description: null,
645
- tags: [],
646
- jsDocTags: [],
647
- }),
648
- MetadataProperty.create({
649
- key: MetadataFactory.soleLiteral("value"),
650
- value: map.value,
651
- description: null,
652
- tags,
653
- jsDocTags: [],
654
- }),
655
- ]),
656
- ts.factory.createExpressionStatement(props.setter()),
657
- ];
658
- return [
659
- ts.factory.createExpressionStatement(
660
- ExpressionFactory.selfCall(
661
- ts.factory.createBlock(statements, true),
662
- ),
663
- ),
664
- ];
665
- };
666
- }
667
-
668
- const PREFIX = "$pd";
669
- const READER = () => ts.factory.createIdentifier("reader");
1
+ import ts from "typescript";
2
+
3
+ import { ExpressionFactory } from "../../factories/ExpressionFactory";
4
+ import { IdentifierFactory } from "../../factories/IdentifierFactory";
5
+ import { MetadataCollection } from "../../factories/MetadataCollection";
6
+ import { MetadataFactory } from "../../factories/MetadataFactory";
7
+ import { ProtobufFactory } from "../../factories/ProtobufFactory";
8
+ import { StatementFactory } from "../../factories/StatementFactory";
9
+ import { TypeFactory } from "../../factories/TypeFactory";
10
+
11
+ import { IMetadataTag } from "../../schemas/metadata/IMetadataTag";
12
+ import { Metadata } from "../../schemas/metadata/Metadata";
13
+ import { MetadataArray } from "../../schemas/metadata/MetadataArray";
14
+ import { MetadataObject } from "../../schemas/metadata/MetadataObject";
15
+ import { MetadataProperty } from "../../schemas/metadata/MetadataProperty";
16
+
17
+ import { IProject } from "../../transformers/IProject";
18
+
19
+ import { Atomic } from "../../typings/Atomic";
20
+
21
+ import { FunctionImporter } from "../helpers/FunctionImporeter";
22
+ import { ProtobufUtil } from "../helpers/ProtobufUtil";
23
+
24
+ export namespace ProtobufDecodeProgrammer {
25
+ export const write =
26
+ (project: IProject) =>
27
+ (modulo: ts.LeftHandSideExpression) =>
28
+ (type: ts.Type, name?: string): ts.ArrowFunction => {
29
+ const importer: FunctionImporter = new FunctionImporter(
30
+ modulo.getText(),
31
+ );
32
+ const collection: MetadataCollection = new MetadataCollection();
33
+ const meta: Metadata = ProtobufFactory.metadata(modulo.getText())(
34
+ project.checker,
35
+ )(collection)(type);
36
+
37
+ const functors = collection
38
+ .objects()
39
+ .filter((obj) => ProtobufUtil.isStaticObject(obj))
40
+ .map((obj) =>
41
+ StatementFactory.constant(
42
+ `${PREFIX}o${obj.index}`,
43
+ write_object_function(project)(importer)(obj),
44
+ ),
45
+ );
46
+ const reader = StatementFactory.constant(
47
+ "reader",
48
+ ts.factory.createNewExpression(
49
+ importer.use("Reader"),
50
+ undefined,
51
+ [ts.factory.createIdentifier("input")],
52
+ ),
53
+ );
54
+
55
+ return ts.factory.createArrowFunction(
56
+ undefined,
57
+ undefined,
58
+ [
59
+ IdentifierFactory.parameter(
60
+ "input",
61
+ ts.factory.createTypeReferenceNode("Uint8Array"),
62
+ ),
63
+ ],
64
+ ts.factory.createTypeReferenceNode(
65
+ `typia.Resolved<${
66
+ name ?? TypeFactory.getFullName(project.checker)(type)
67
+ }>`,
68
+ ),
69
+ undefined,
70
+ ts.factory.createBlock(
71
+ [
72
+ ...importer.declare(modulo),
73
+ ...functors,
74
+ reader,
75
+ ts.factory.createReturnStatement(
76
+ decode_regular_object(true)(meta.objects[0]!),
77
+ ),
78
+ ],
79
+ true,
80
+ ),
81
+ );
82
+ };
83
+
84
+ const write_object_function =
85
+ (project: IProject) =>
86
+ (importer: FunctionImporter) =>
87
+ (obj: MetadataObject): ts.ArrowFunction =>
88
+ ts.factory.createArrowFunction(
89
+ undefined,
90
+ undefined,
91
+ [
92
+ IdentifierFactory.parameter("reader"),
93
+ IdentifierFactory.parameter(
94
+ "length",
95
+ TypeFactory.keyword("number"),
96
+ ts.factory.createNumericLiteral(-1),
97
+ ),
98
+ ],
99
+ TypeFactory.keyword("any"),
100
+ undefined,
101
+ ts.factory.createBlock(
102
+ [
103
+ ts.factory.createExpressionStatement(
104
+ ts.factory.createBinaryExpression(
105
+ ts.factory.createIdentifier("length"),
106
+ ts.factory.createToken(
107
+ ts.SyntaxKind.EqualsToken,
108
+ ),
109
+ ts.factory.createConditionalExpression(
110
+ ts.factory.createLessThan(
111
+ ts.factory.createIdentifier("length"),
112
+ ts.factory.createNumericLiteral(0),
113
+ ),
114
+ undefined,
115
+ ts.factory.createCallExpression(
116
+ IdentifierFactory.access(READER())(
117
+ "size",
118
+ ),
119
+ undefined,
120
+ undefined,
121
+ ),
122
+ undefined,
123
+ ts.factory.createAdd(
124
+ ts.factory.createCallExpression(
125
+ IdentifierFactory.access(READER())(
126
+ "index",
127
+ ),
128
+ undefined,
129
+ undefined,
130
+ ),
131
+ ts.factory.createIdentifier("length"),
132
+ ),
133
+ ),
134
+ ),
135
+ ),
136
+ ...write_object_function_body(project)(importer)({
137
+ condition: ts.factory.createLessThan(
138
+ ts.factory.createCallExpression(
139
+ IdentifierFactory.access(READER())("index"),
140
+ undefined,
141
+ undefined,
142
+ ),
143
+ ts.factory.createIdentifier("length"),
144
+ ),
145
+ tag: "tag",
146
+ output: "output",
147
+ })(obj.properties),
148
+ ts.factory.createReturnStatement(
149
+ ts.factory.createIdentifier("output"),
150
+ ),
151
+ ],
152
+ true,
153
+ ),
154
+ );
155
+
156
+ const write_object_function_body =
157
+ (project: IProject) =>
158
+ (importer: FunctionImporter) =>
159
+ (props: { condition: ts.Expression; tag: string; output: string }) =>
160
+ (properties: MetadataProperty[]): ts.Statement[] => {
161
+ let i: number = 1;
162
+ const clauses: ts.CaseClause[] = properties
163
+ .map((p) => {
164
+ const clause = decode_property(project)(importer)(i)(
165
+ IdentifierFactory.access(
166
+ ts.factory.createIdentifier(props.output),
167
+ )(p.key.getSoleLiteral()!),
168
+ p.value,
169
+ p.tags,
170
+ );
171
+ i += p.value.binarySize();
172
+ return clause;
173
+ })
174
+ .flat();
175
+ return [
176
+ StatementFactory.constant(
177
+ props.output,
178
+ ts.factory.createObjectLiteralExpression(
179
+ properties.map((p) =>
180
+ ts.factory.createPropertyAssignment(
181
+ IdentifierFactory.identifier(
182
+ p.key.getSoleLiteral()!,
183
+ ),
184
+ write_property_default_value(p.value),
185
+ ),
186
+ ),
187
+ true,
188
+ ),
189
+ ),
190
+ ts.factory.createWhileStatement(
191
+ props.condition,
192
+ ts.factory.createBlock([
193
+ StatementFactory.constant(
194
+ props.tag,
195
+ ts.factory.createCallExpression(
196
+ IdentifierFactory.access(READER())("uint32"),
197
+ undefined,
198
+ undefined,
199
+ ),
200
+ ),
201
+ ts.factory.createSwitchStatement(
202
+ ts.factory.createUnsignedRightShift(
203
+ ts.factory.createIdentifier(props.tag),
204
+ ts.factory.createNumericLiteral(3),
205
+ ),
206
+ ts.factory.createCaseBlock([
207
+ ...clauses,
208
+ ts.factory.createDefaultClause([
209
+ ts.factory.createExpressionStatement(
210
+ ts.factory.createCallExpression(
211
+ IdentifierFactory.access(READER())(
212
+ "skipType",
213
+ ),
214
+ undefined,
215
+ [
216
+ ts.factory.createBitwiseAnd(
217
+ ts.factory.createIdentifier(
218
+ props.tag,
219
+ ),
220
+ ts.factory.createNumericLiteral(
221
+ 7,
222
+ ),
223
+ ),
224
+ ],
225
+ ),
226
+ ),
227
+ ts.factory.createBreakStatement(),
228
+ ]),
229
+ ]),
230
+ ),
231
+ ]),
232
+ ),
233
+ ];
234
+ };
235
+
236
+ const write_property_default_value = (value: Metadata) =>
237
+ ts.factory.createAsExpression(
238
+ value.nullable
239
+ ? ts.factory.createNull()
240
+ : value.isRequired() === false
241
+ ? ts.factory.createIdentifier("undefined")
242
+ : value.arrays.length
243
+ ? ts.factory.createArrayLiteralExpression()
244
+ : value.maps.length
245
+ ? ts.factory.createNewExpression(
246
+ ts.factory.createIdentifier("Map"),
247
+ undefined,
248
+ [],
249
+ )
250
+ : value.natives.length
251
+ ? ts.factory.createNewExpression(
252
+ ts.factory.createIdentifier("Uint8Array"),
253
+ undefined,
254
+ [],
255
+ )
256
+ : value.atomics.some((a) => a.type === "string") ||
257
+ value.constants.some(
258
+ (c) =>
259
+ c.type === "string" && c.values.some((v) => v === ""),
260
+ ) ||
261
+ value.templates.some(
262
+ (tpl) =>
263
+ tpl.length === 1 && tpl[0]!.getName() === "string",
264
+ )
265
+ ? ts.factory.createStringLiteral("")
266
+ : value.objects.length &&
267
+ value.objects.some((obj) => !ProtobufUtil.isStaticObject(obj))
268
+ ? ts.factory.createObjectLiteralExpression()
269
+ : ts.factory.createIdentifier("undefined"),
270
+ TypeFactory.keyword("any"),
271
+ );
272
+
273
+ /* -----------------------------------------------------------
274
+ DECODERS
275
+ ----------------------------------------------------------- */
276
+ const decode_property =
277
+ (project: IProject) =>
278
+ (importer: FunctionImporter) =>
279
+ (index: number) =>
280
+ (
281
+ accessor: ts.ElementAccessExpression | ts.PropertyAccessExpression,
282
+ meta: Metadata,
283
+ tags: IMetadataTag[],
284
+ ): ts.CaseClause[] => {
285
+ const clauses: ts.CaseClause[] = [];
286
+ const emplace =
287
+ (name: string) => (v: ts.Expression | ts.Statement[]) =>
288
+ clauses.push(
289
+ ts.factory.createCaseClause(
290
+ ts.factory.createNumericLiteral(index++),
291
+ Array.isArray(v)
292
+ ? [
293
+ ts.factory.createExpressionStatement(
294
+ ts.factory.createIdentifier(
295
+ `// type: ${name}`,
296
+ ),
297
+ ),
298
+ ...v,
299
+ ts.factory.createBreakStatement(),
300
+ ]
301
+ : [
302
+ ts.factory.createExpressionStatement(
303
+ ts.factory.createIdentifier(
304
+ `// ${name}`,
305
+ ),
306
+ ),
307
+ ts.factory.createExpressionStatement(
308
+ ts.factory.createBinaryExpression(
309
+ accessor,
310
+ ts.factory.createToken(
311
+ ts.SyntaxKind.EqualsToken,
312
+ ),
313
+ v,
314
+ ),
315
+ ),
316
+ ts.factory.createBreakStatement(),
317
+ ],
318
+ ),
319
+ );
320
+
321
+ const required: boolean = meta.isRequired() && !meta.nullable;
322
+ for (const atomic of ProtobufUtil.getAtomics(meta))
323
+ emplace(atomic)(decode_atomic(atomic, tags));
324
+ if (meta.natives.length) emplace("bytes")(decode_bytes("bytes"));
325
+ for (const array of meta.arrays)
326
+ emplace(`Array<${array.value.getName()}>`)(
327
+ decode_array(accessor, array, required, tags),
328
+ );
329
+ for (const map of meta.maps)
330
+ emplace(`Map<string, ${map.value.getName()}>`)(
331
+ decode_map(project)(importer)(
332
+ accessor,
333
+ map,
334
+ required,
335
+ tags,
336
+ ),
337
+ );
338
+ for (const obj of meta.objects)
339
+ emplace(obj.name)(
340
+ ProtobufUtil.isStaticObject(obj)
341
+ ? decode_regular_object(false)(obj)
342
+ : decode_dynamic_object(project)(importer)(
343
+ accessor,
344
+ obj,
345
+ required,
346
+ ),
347
+ );
348
+ return clauses;
349
+ };
350
+
351
+ const decode_atomic = (
352
+ atomic: Atomic.Literal,
353
+ tags: IMetadataTag[],
354
+ ): ts.Expression => {
355
+ if (atomic === "string") return decode_bytes("string");
356
+ const method =
357
+ atomic === "bigint"
358
+ ? tags.find((t) => t.kind === "type" && t.value === "uint64")
359
+ ? "uint64"
360
+ : "int64"
361
+ : atomic === "number"
362
+ ? (() => {
363
+ const type = tags.find((t) => t.kind === "type");
364
+ if (type === undefined) return "double";
365
+ return type.value === "int" || type.value === "int32"
366
+ ? "int32"
367
+ : type.value === "uint" || type.value === "uint32"
368
+ ? "uint32"
369
+ : type.value === "int64"
370
+ ? "int64"
371
+ : type.value === "uint64"
372
+ ? "uint64"
373
+ : type.value === "float"
374
+ ? "float"
375
+ : "double";
376
+ })()
377
+ : "bool";
378
+ const call = ts.factory.createCallExpression(
379
+ IdentifierFactory.access(ts.factory.createIdentifier("reader"))(
380
+ method,
381
+ ),
382
+ undefined,
383
+ undefined,
384
+ );
385
+ return atomic === "number" &&
386
+ (method === "int64" || method === "uint64")
387
+ ? ts.factory.createCallExpression(
388
+ ts.factory.createIdentifier("Number"),
389
+ undefined,
390
+ [call],
391
+ )
392
+ : call;
393
+ };
394
+
395
+ const decode_bytes = (method: "bytes" | "string"): ts.Expression =>
396
+ ts.factory.createCallExpression(
397
+ IdentifierFactory.access(ts.factory.createIdentifier("reader"))(
398
+ method,
399
+ ),
400
+ undefined,
401
+ undefined,
402
+ );
403
+
404
+ const decode_array = (
405
+ accessor: ts.ElementAccessExpression | ts.PropertyAccessExpression,
406
+ array: MetadataArray,
407
+ required: boolean,
408
+ tags: IMetadataTag[],
409
+ ): ts.Statement[] => {
410
+ const statements: Array<ts.Expression | ts.Statement> = [];
411
+ if (required === false)
412
+ statements.push(
413
+ ts.factory.createBinaryExpression(
414
+ accessor,
415
+ ts.factory.createToken(
416
+ ts.SyntaxKind.QuestionQuestionEqualsToken,
417
+ ),
418
+ ts.factory.createAsExpression(
419
+ ts.factory.createArrayLiteralExpression(),
420
+ ts.factory.createTypeReferenceNode("any[]"),
421
+ ),
422
+ ),
423
+ );
424
+ const atomics = ProtobufUtil.getAtomics(array.value);
425
+ const decoder = atomics.length
426
+ ? () => decode_atomic(atomics[0]!, tags)
427
+ : array.value.natives.length
428
+ ? () => decode_bytes("bytes")
429
+ : array.value.objects.length
430
+ ? () => decode_regular_object(false)(array.value.objects[0]!)
431
+ : null;
432
+ if (decoder === null) throw new Error("Never reach here.");
433
+ else if (atomics.length && atomics[0] !== "string") {
434
+ statements.push(
435
+ ts.factory.createIfStatement(
436
+ ts.factory.createStrictEquality(
437
+ ts.factory.createNumericLiteral(2),
438
+ ts.factory.createBitwiseAnd(
439
+ ts.factory.createIdentifier("tag"),
440
+ ts.factory.createNumericLiteral(7),
441
+ ),
442
+ ),
443
+ ts.factory.createBlock(
444
+ [
445
+ StatementFactory.constant(
446
+ "piece",
447
+ ts.factory.createAdd(
448
+ ts.factory.createCallExpression(
449
+ IdentifierFactory.access(READER())(
450
+ "uint32",
451
+ ),
452
+ undefined,
453
+ undefined,
454
+ ),
455
+ ts.factory.createCallExpression(
456
+ IdentifierFactory.access(READER())(
457
+ "index",
458
+ ),
459
+ undefined,
460
+ undefined,
461
+ ),
462
+ ),
463
+ ),
464
+ ts.factory.createWhileStatement(
465
+ ts.factory.createLessThan(
466
+ ts.factory.createCallExpression(
467
+ IdentifierFactory.access(READER())(
468
+ "index",
469
+ ),
470
+ undefined,
471
+ undefined,
472
+ ),
473
+ ts.factory.createIdentifier("piece"),
474
+ ),
475
+ ts.factory.createExpressionStatement(
476
+ ts.factory.createCallExpression(
477
+ IdentifierFactory.access(accessor)(
478
+ "push",
479
+ ),
480
+ undefined,
481
+ [decoder()],
482
+ ),
483
+ ),
484
+ ),
485
+ ],
486
+ true,
487
+ ),
488
+ ts.factory.createExpressionStatement(
489
+ ts.factory.createCallExpression(
490
+ IdentifierFactory.access(accessor)("push"),
491
+ undefined,
492
+ [decoder()],
493
+ ),
494
+ ),
495
+ ),
496
+ );
497
+ } else
498
+ statements.push(
499
+ ts.factory.createCallExpression(
500
+ IdentifierFactory.access(accessor)("push"),
501
+ undefined,
502
+ [decoder()],
503
+ ),
504
+ );
505
+ return statements.map((stmt) =>
506
+ ts.isExpression(stmt)
507
+ ? ts.factory.createExpressionStatement(stmt)
508
+ : stmt,
509
+ );
510
+ };
511
+
512
+ const decode_regular_object =
513
+ (top: boolean) =>
514
+ (obj: MetadataObject): ts.Expression =>
515
+ ts.factory.createCallExpression(
516
+ ts.factory.createIdentifier(`${PREFIX}o${obj.index}`),
517
+ undefined,
518
+ [
519
+ ts.factory.createIdentifier("reader"),
520
+ ...(top
521
+ ? []
522
+ : [
523
+ ts.factory.createCallExpression(
524
+ IdentifierFactory.access(READER())("uint32"),
525
+ undefined,
526
+ undefined,
527
+ ),
528
+ ]),
529
+ ],
530
+ );
531
+
532
+ const decode_dynamic_object =
533
+ (project: IProject) =>
534
+ (importer: FunctionImporter) =>
535
+ (
536
+ accessor: ts.ElementAccessExpression | ts.PropertyAccessExpression,
537
+ obj: MetadataObject,
538
+ required: boolean,
539
+ ): ts.Statement[] => {
540
+ const top = obj.properties[0]!;
541
+ return decode_entry(project)(importer)({
542
+ initializer: () =>
543
+ ts.factory.createBinaryExpression(
544
+ accessor,
545
+ ts.factory.createToken(
546
+ ts.SyntaxKind.QuestionQuestionEqualsToken,
547
+ ),
548
+ ts.factory.createObjectLiteralExpression(),
549
+ ),
550
+ setter: () =>
551
+ ts.factory.createBinaryExpression(
552
+ ts.factory.createElementAccessExpression(
553
+ accessor,
554
+ ts.factory.createIdentifier("entry.key"),
555
+ ),
556
+ ts.factory.createToken(ts.SyntaxKind.EqualsToken),
557
+ ts.factory.createIdentifier("entry.value"),
558
+ ),
559
+ })(top, required, top.tags);
560
+ };
561
+
562
+ const decode_map =
563
+ (project: IProject) =>
564
+ (importer: FunctionImporter) =>
565
+ (
566
+ accessor: ts.ElementAccessExpression | ts.PropertyAccessExpression,
567
+ map: Metadata.Entry,
568
+ required: boolean,
569
+ tags: IMetadataTag[],
570
+ ): ts.Statement[] =>
571
+ decode_entry(project)(importer)({
572
+ initializer: () =>
573
+ ts.factory.createBinaryExpression(
574
+ accessor,
575
+ ts.factory.createToken(
576
+ ts.SyntaxKind.QuestionQuestionEqualsToken,
577
+ ),
578
+ ts.factory.createNewExpression(
579
+ ts.factory.createIdentifier("Map"),
580
+ [
581
+ TypeFactory.keyword("any"),
582
+ TypeFactory.keyword("any"),
583
+ ],
584
+ [],
585
+ ),
586
+ ),
587
+ setter: () =>
588
+ ts.factory.createCallExpression(
589
+ IdentifierFactory.access(accessor)("set"),
590
+ undefined,
591
+ [
592
+ ts.factory.createIdentifier("entry.key"),
593
+ ts.factory.createIdentifier("entry.value"),
594
+ ],
595
+ ),
596
+ })(map, required, tags);
597
+
598
+ const decode_entry =
599
+ (project: IProject) =>
600
+ (importer: FunctionImporter) =>
601
+ (props: {
602
+ initializer: () => ts.Expression;
603
+ setter: () => ts.Expression;
604
+ }) =>
605
+ (
606
+ map: Metadata.Entry,
607
+ required: boolean,
608
+ tags: IMetadataTag[],
609
+ ): ts.Statement[] => {
610
+ const statements: ts.Statement[] = [
611
+ ...(required
612
+ ? []
613
+ : [
614
+ ts.factory.createExpressionStatement(
615
+ props.initializer(),
616
+ ),
617
+ ]),
618
+ StatementFactory.constant(
619
+ "piece",
620
+ ts.factory.createAdd(
621
+ ts.factory.createCallExpression(
622
+ IdentifierFactory.access(READER())("uint32"),
623
+ undefined,
624
+ undefined,
625
+ ),
626
+ ts.factory.createCallExpression(
627
+ IdentifierFactory.access(READER())("index"),
628
+ undefined,
629
+ undefined,
630
+ ),
631
+ ),
632
+ ),
633
+ ...write_object_function_body(project)(importer)({
634
+ condition: ts.factory.createLessThan(
635
+ ts.factory.createCallExpression(
636
+ IdentifierFactory.access(READER())("index"),
637
+ undefined,
638
+ undefined,
639
+ ),
640
+ ts.factory.createIdentifier("piece"),
641
+ ),
642
+ tag: "kind",
643
+ output: "entry",
644
+ })([
645
+ MetadataProperty.create({
646
+ key: MetadataFactory.soleLiteral("key"),
647
+ value: map.key,
648
+ description: null,
649
+ tags: [],
650
+ jsDocTags: [],
651
+ }),
652
+ MetadataProperty.create({
653
+ key: MetadataFactory.soleLiteral("value"),
654
+ value: map.value,
655
+ description: null,
656
+ tags,
657
+ jsDocTags: [],
658
+ }),
659
+ ]),
660
+ ts.factory.createExpressionStatement(props.setter()),
661
+ ];
662
+ return [
663
+ ts.factory.createExpressionStatement(
664
+ ExpressionFactory.selfCall(
665
+ ts.factory.createBlock(statements, true),
666
+ ),
667
+ ),
668
+ ];
669
+ };
670
+ }
671
+
672
+ const PREFIX = "$pd";
673
+ const READER = () => ts.factory.createIdentifier("reader");