typia 4.1.6 → 5.0.0-dev.20230711

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 (139) hide show
  1. package/README.md +9 -1
  2. package/lib/factories/MetadataTagFactory.js +11 -4
  3. package/lib/factories/MetadataTagFactory.js.map +1 -1
  4. package/lib/factories/ProtocolFactory.d.ts +8 -0
  5. package/lib/factories/ProtocolFactory.js +113 -0
  6. package/lib/factories/ProtocolFactory.js.map +1 -0
  7. package/lib/factories/internal/protocols/ProtocolMetadataUtil.d.ts +16 -0
  8. package/lib/factories/internal/protocols/ProtocolMetadataUtil.js +173 -0
  9. package/lib/factories/internal/protocols/ProtocolMetadataUtil.js.map +1 -0
  10. package/lib/factories/internal/protocols/emplace_protocol_object.d.ts +3 -0
  11. package/lib/factories/internal/protocols/emplace_protocol_object.js +47 -0
  12. package/lib/factories/internal/protocols/emplace_protocol_object.js.map +1 -0
  13. package/lib/factories/internal/protocols/emplace_protocol_property.d.ts +4 -0
  14. package/lib/factories/internal/protocols/emplace_protocol_property.js +20 -0
  15. package/lib/factories/internal/protocols/emplace_protocol_property.js.map +1 -0
  16. package/lib/factories/internal/protocols/iterate_protocol_atomic.d.ts +3 -0
  17. package/lib/factories/internal/protocols/iterate_protocol_atomic.js +69 -0
  18. package/lib/factories/internal/protocols/iterate_protocol_atomic.js.map +1 -0
  19. package/lib/factories/internal/protocols/iterate_protocol_constant.d.ts +2 -0
  20. package/lib/factories/internal/protocols/iterate_protocol_constant.js +30 -0
  21. package/lib/factories/internal/protocols/iterate_protocol_constant.js.map +1 -0
  22. package/lib/factories/internal/protocols/iterate_protocol_main.d.ts +3 -0
  23. package/lib/factories/internal/protocols/iterate_protocol_main.js +17 -0
  24. package/lib/factories/internal/protocols/iterate_protocol_main.js.map +1 -0
  25. package/lib/factories/internal/protocols/iterate_protocol_map.d.ts +4 -0
  26. package/lib/factories/internal/protocols/iterate_protocol_map.js +75 -0
  27. package/lib/factories/internal/protocols/iterate_protocol_map.js.map +1 -0
  28. package/lib/factories/internal/protocols/iterate_protocol_metadata.d.ts +5 -0
  29. package/lib/factories/internal/protocols/iterate_protocol_metadata.js +190 -0
  30. package/lib/factories/internal/protocols/iterate_protocol_metadata.js.map +1 -0
  31. package/lib/factories/internal/protocols/iterate_protocol_native.d.ts +2 -0
  32. package/lib/factories/internal/protocols/iterate_protocol_native.js +33 -0
  33. package/lib/factories/internal/protocols/iterate_protocol_native.js.map +1 -0
  34. package/lib/factories/internal/protocols/iterate_protocol_never.d.ts +1 -0
  35. package/lib/factories/internal/protocols/iterate_protocol_never.js +6 -0
  36. package/lib/factories/internal/protocols/iterate_protocol_never.js.map +1 -0
  37. package/lib/factories/internal/protocols/iterate_protocol_object.d.ts +4 -0
  38. package/lib/factories/internal/protocols/iterate_protocol_object.js +157 -0
  39. package/lib/factories/internal/protocols/iterate_protocol_object.js.map +1 -0
  40. package/lib/factories/internal/protocols/iterate_protocol_repeated.d.ts +5 -0
  41. package/lib/factories/internal/protocols/iterate_protocol_repeated.js +25 -0
  42. package/lib/factories/internal/protocols/iterate_protocol_repeated.js.map +1 -0
  43. package/lib/factories/internal/protocols/iterate_protocol_tuple.d.ts +3 -0
  44. package/lib/factories/internal/protocols/iterate_protocol_tuple.js +46 -0
  45. package/lib/factories/internal/protocols/iterate_protocol_tuple.js.map +1 -0
  46. package/lib/functional/$proto_bytes.d.ts +2 -0
  47. package/lib/functional/$proto_bytes.js +37 -0
  48. package/lib/functional/$proto_bytes.js.map +1 -0
  49. package/lib/functional/$proto_field.d.ts +10 -0
  50. package/lib/functional/$proto_field.js +42 -0
  51. package/lib/functional/$proto_field.js.map +1 -0
  52. package/lib/functional/$proto_float.d.ts +4 -0
  53. package/lib/functional/$proto_float.js +28 -0
  54. package/lib/functional/$proto_float.js.map +1 -0
  55. package/lib/functional/$proto_i32.d.ts +2 -0
  56. package/lib/functional/$proto_i32.js +23 -0
  57. package/lib/functional/$proto_i32.js.map +1 -0
  58. package/lib/functional/$proto_i64.d.ts +2 -0
  59. package/lib/functional/$proto_i64.js +31 -0
  60. package/lib/functional/$proto_i64.js.map +1 -0
  61. package/lib/functional/$proto_size.d.ts +6 -0
  62. package/lib/functional/$proto_size.js +76 -0
  63. package/lib/functional/$proto_size.js.map +1 -0
  64. package/lib/functional/$proto_string.d.ts +2 -0
  65. package/lib/functional/$proto_string.js +34 -0
  66. package/lib/functional/$proto_string.js.map +1 -0
  67. package/lib/functional/$varint.d.ts +6 -0
  68. package/lib/functional/$varint.js +99 -0
  69. package/lib/functional/$varint.js.map +1 -0
  70. package/lib/functional/$zigzag.d.ts +4 -0
  71. package/lib/functional/$zigzag.js +34 -0
  72. package/lib/functional/$zigzag.js.map +1 -0
  73. package/lib/messages/IProtocolMap.d.ts +5 -0
  74. package/lib/messages/IProtocolMap.js +3 -0
  75. package/lib/messages/IProtocolMap.js.map +1 -0
  76. package/lib/messages/IProtocolMessage.d.ts +5 -0
  77. package/lib/messages/IProtocolMessage.js +3 -0
  78. package/lib/messages/IProtocolMessage.js.map +1 -0
  79. package/lib/messages/IProtocolProperty.d.ts +12 -0
  80. package/lib/messages/IProtocolProperty.js +3 -0
  81. package/lib/messages/IProtocolProperty.js.map +1 -0
  82. package/lib/metadata/IMetadataTag.d.ts +3 -3
  83. package/lib/metadata/Metadata.js.map +1 -1
  84. package/lib/module.d.ts +2 -0
  85. package/lib/module.js +6 -1
  86. package/lib/module.js.map +1 -1
  87. package/lib/programmers/MessageProgrammer.d.ts +5 -0
  88. package/lib/programmers/MessageProgrammer.js +141 -0
  89. package/lib/programmers/MessageProgrammer.js.map +1 -0
  90. package/lib/programmers/internal/application_number.js +8 -5
  91. package/lib/programmers/internal/application_number.js.map +1 -1
  92. package/lib/transformers/CallExpressionTransformer.js +5 -3
  93. package/lib/transformers/CallExpressionTransformer.js.map +1 -1
  94. package/lib/transformers/features/miscellaneous/ApplicationTransformer.js +1 -3
  95. package/lib/transformers/features/miscellaneous/ApplicationTransformer.js.map +1 -1
  96. package/lib/transformers/features/protocols/MessageTransformer.d.ts +5 -0
  97. package/lib/transformers/features/protocols/MessageTransformer.js +20 -0
  98. package/lib/transformers/features/protocols/MessageTransformer.js.map +1 -0
  99. package/lib/utils/NameEncoder.d.ts +4 -0
  100. package/lib/utils/NameEncoder.js +89 -0
  101. package/lib/utils/NameEncoder.js.map +1 -0
  102. package/package.json +1 -1
  103. package/src/factories/MetadataTagFactory.ts +10 -3
  104. package/src/factories/ProtocolFactory.ts +80 -0
  105. package/src/factories/internal/protocols/ProtocolMetadataUtil.ts +180 -0
  106. package/src/factories/internal/protocols/emplace_protocol_object.ts +25 -0
  107. package/src/factories/internal/protocols/emplace_protocol_property.ts +12 -0
  108. package/src/factories/internal/protocols/iterate_protocol_atomic.ts +34 -0
  109. package/src/factories/internal/protocols/iterate_protocol_constant.ts +27 -0
  110. package/src/factories/internal/protocols/iterate_protocol_main.ts +19 -0
  111. package/src/factories/internal/protocols/iterate_protocol_map.ts +58 -0
  112. package/src/factories/internal/protocols/iterate_protocol_metadata.ts +96 -0
  113. package/src/factories/internal/protocols/iterate_protocol_native.ts +34 -0
  114. package/src/factories/internal/protocols/iterate_protocol_never.ts +1 -0
  115. package/src/factories/internal/protocols/iterate_protocol_object.ts +110 -0
  116. package/src/factories/internal/protocols/iterate_protocol_repeated.ts +34 -0
  117. package/src/factories/internal/protocols/iterate_protocol_tuple.ts +29 -0
  118. package/src/functional/$proto_bytes.ts +25 -0
  119. package/src/functional/$proto_field.ts +30 -0
  120. package/src/functional/$proto_float.ts +37 -0
  121. package/src/functional/$proto_i32.ts +29 -0
  122. package/src/functional/$proto_i64.ts +37 -0
  123. package/src/functional/$proto_size.ts +82 -0
  124. package/src/functional/$proto_string.ts +24 -0
  125. package/src/functional/$varint.ts +130 -0
  126. package/src/functional/$zigzag.ts +39 -0
  127. package/src/messages/IProtocolMap.ts +5 -0
  128. package/src/messages/IProtocolMessage.ts +6 -0
  129. package/src/messages/IProtocolProperty.ts +13 -0
  130. package/src/metadata/IMetadataTag.ts +11 -3
  131. package/src/metadata/Metadata.ts +3 -0
  132. package/src/module.ts +11 -0
  133. package/src/programmers/MessageProgrammer.ts +126 -0
  134. package/src/programmers/internal/application_number.ts +10 -7
  135. package/src/transformers/CallExpressionTransformer.ts +17 -10
  136. package/src/transformers/features/miscellaneous/ApplicationTransformer.ts +1 -3
  137. package/src/transformers/features/protocols/MessageTransformer.ts +31 -0
  138. package/src/utils/Escaper.ts +46 -46
  139. package/src/utils/NameEncoder.ts +32 -0
@@ -0,0 +1,80 @@
1
+ import ts from "typescript";
2
+
3
+ import { Metadata } from "../metadata/Metadata";
4
+
5
+ import { IProtocolMessage } from "../messages/IProtocolMessage";
6
+ import { MetadataCollection } from "./MetadataCollection";
7
+ import { MetadataFactory } from "./MetadataFactory";
8
+ import { emplace_protocol_object } from "./internal/protocols/emplace_protocol_object";
9
+ import { iterate_protocol_main } from "./internal/protocols/iterate_protocol_main";
10
+
11
+ export namespace ProtocolFactory {
12
+ export const metadata =
13
+ (checker: ts.TypeChecker) =>
14
+ (collection: MetadataCollection) =>
15
+ (type: ts.Type) =>
16
+ MetadataFactory.analyze(checker)({
17
+ resolve: false,
18
+ constant: true,
19
+ absorb: true,
20
+ validate: (meta) => {
21
+ if (meta.any) throw new Error(ErrorMessages.NO_ANY);
22
+ else if (meta.functional && meta.size() !== 1)
23
+ throw new Error(ErrorMessages.NO_FUNCTIONAL);
24
+ else if (meta.objects.find((o) => o.name === "__Main"))
25
+ throw new Error(ErrorMessages.NO_MAIN);
26
+ else if (meta.objects.find((o) => o.name === "__Timestamp"))
27
+ throw new Error(ErrorMessages.NO_TIMESTAMP);
28
+ else if (
29
+ meta.objects.some((o) =>
30
+ o.properties.some((p) => !is_atomic_key(p.key)),
31
+ ) ||
32
+ meta.maps.some((m) => !is_atomic_key(m.key))
33
+ )
34
+ throw new Error(ErrorMessages.NOT_ALLOWED_KEY);
35
+ },
36
+ })(collection)(type);
37
+
38
+ export const generate =
39
+ (collection: MetadataCollection) =>
40
+ (dict: Map<string, IProtocolMessage>) =>
41
+ (meta: Metadata) => {
42
+ // EMPLACE OBJECTS
43
+ for (const obj of collection.objects())
44
+ emplace_protocol_object(dict)(obj);
45
+
46
+ // WHEN NOT OBJECT, WRAP IT INTO A FAKE MAIN OBJECT
47
+ iterate_protocol_main(dict)(meta);
48
+ };
49
+
50
+ const is_atomic_key = (key: Metadata) => {
51
+ if (
52
+ key.required &&
53
+ key.nullable === false &&
54
+ key.functional === false &&
55
+ key.resolved === null &&
56
+ key.size() ===
57
+ key.atomics.length +
58
+ key.constants
59
+ .map((c) => c.values.length)
60
+ .reduce((a, b) => a + b, 0) +
61
+ key.templates.length
62
+ ) {
63
+ const set: Set<string> = new Set();
64
+ for (const atomic of key.atomics) set.add(atomic);
65
+ for (const constant of key.constants) set.add(constant.type);
66
+ if (key.templates.length) set.add("string");
67
+
68
+ return set.size === 1;
69
+ }
70
+ return false;
71
+ };
72
+ }
73
+
74
+ const enum ErrorMessages {
75
+ NO_ANY = `Error on typia.message(): any type is not supported in protocol buffer.`,
76
+ NO_FUNCTIONAL = `Error on typia.message(): functional type is not supported in protocol buffer.`,
77
+ NO_MAIN = `Error on typia.message(): reserved type "__Main" has been detected.`,
78
+ NO_TIMESTAMP = `Error on typia.message(): reserved type "__Timestamp" has been detected.`,
79
+ NOT_ALLOWED_KEY = `Error on typia.message(): only atomic key type is supported in protocol buffer.`,
80
+ }
@@ -0,0 +1,180 @@
1
+ import { IMetadataTag } from "../../../metadata/IMetadataTag";
2
+ import { Metadata } from "../../../metadata/Metadata";
3
+ import { MetadataArray } from "../../../metadata/MetadataArray";
4
+ import { MetadataObject } from "../../../metadata/MetadataObject";
5
+ import { MetadataProperty } from "../../../metadata/MetadataProperty";
6
+
7
+ import { Atomic } from "../../../typings/Atomic";
8
+
9
+ export namespace ProtocolMetadataUtil {
10
+ export function size(meta: Metadata): number {
11
+ return (
12
+ meta.atomics.length +
13
+ meta.constants.filter(
14
+ (c) =>
15
+ meta.atomics.find((type) => c.type === type) === undefined,
16
+ ).length +
17
+ (meta.templates.length !== 0 &&
18
+ meta.atomics.find((type) => type === "string") === undefined &&
19
+ meta.constants.find((c) => c.type === "string") === undefined
20
+ ? 1
21
+ : 0) +
22
+ meta.tuples.length +
23
+ meta.arrays.length +
24
+ meta.sets.length +
25
+ meta.maps.length +
26
+ meta.objects.length +
27
+ meta.natives.filter((n) => n === "Date").length +
28
+ (meta.natives.filter((n) => n !== "Date").length ? 1 : 0)
29
+ );
30
+ }
31
+
32
+ export function standalone(meta: Metadata): boolean {
33
+ return (
34
+ size(meta) === 1 &&
35
+ meta.required === true &&
36
+ meta.nullable === false &&
37
+ meta.tuples.length === 0 &&
38
+ meta.arrays.length === 0 &&
39
+ meta.sets.length === 0 &&
40
+ meta.maps.length === 0 &&
41
+ meta.objects.every((obj) =>
42
+ obj.properties.every((p) => p.key.isSoleLiteral()),
43
+ )
44
+ );
45
+ }
46
+
47
+ export function regular(obj: MetadataObject): boolean {
48
+ return obj.properties.every((p) => p.key.isSoleLiteral());
49
+ }
50
+
51
+ export function object(name: string, index: number): MetadataObject {
52
+ return MetadataObject.create({
53
+ name,
54
+ index,
55
+ properties: [],
56
+ description: undefined,
57
+ jsDocTags: [],
58
+ validated: false,
59
+ recursive: false,
60
+ nullables: [false],
61
+ });
62
+ }
63
+
64
+ export function property(
65
+ key: string,
66
+ value: Metadata,
67
+ tags: IMetadataTag[],
68
+ ): MetadataProperty {
69
+ return MetadataProperty.create({
70
+ key: (() => {
71
+ const meta: Metadata = Metadata.initialize();
72
+ meta.constants.push({
73
+ type: "string",
74
+ values: [key],
75
+ });
76
+ return meta;
77
+ })(),
78
+ value: value,
79
+ description: null,
80
+ tags,
81
+ jsDocTags: [],
82
+ });
83
+ }
84
+
85
+ export function array(meta: Metadata): Metadata {
86
+ return Metadata.create({
87
+ any: false,
88
+ required: true,
89
+ optional: false,
90
+ nullable: false,
91
+ functional: false,
92
+ resolved: null,
93
+ aliases: [],
94
+ atomics: [],
95
+ constants: [],
96
+ templates: [],
97
+ rest: null,
98
+ arrays: [
99
+ MetadataArray.create({
100
+ name: meta.getName(),
101
+ value: meta,
102
+ nullables: [false],
103
+ recursive: false,
104
+ index: null,
105
+ }),
106
+ ],
107
+ tuples: [],
108
+ objects: [],
109
+ natives: [],
110
+ sets: [],
111
+ maps: [],
112
+ });
113
+ }
114
+
115
+ export function atomic(type: Atomic.Literal): Metadata {
116
+ return Metadata.create({
117
+ any: false,
118
+ required: true,
119
+ optional: false,
120
+ nullable: false,
121
+ functional: false,
122
+ resolved: null,
123
+ aliases: [],
124
+ atomics: [type],
125
+ constants: [],
126
+ templates: [],
127
+ rest: null,
128
+ arrays: [],
129
+ tuples: [],
130
+ objects: [],
131
+ natives: [],
132
+ sets: [],
133
+ maps: [],
134
+ });
135
+ }
136
+
137
+ export function reference(obj: MetadataObject): Metadata {
138
+ return Metadata.create({
139
+ any: false,
140
+ required: true,
141
+ optional: false,
142
+ nullable: false,
143
+ functional: false,
144
+ resolved: null,
145
+ aliases: [],
146
+ atomics: [],
147
+ constants: [],
148
+ templates: [],
149
+ rest: null,
150
+ arrays: [],
151
+ tuples: [],
152
+ objects: [obj],
153
+ natives: [],
154
+ sets: [],
155
+ maps: [],
156
+ });
157
+ }
158
+
159
+ export function map(elem: Metadata.Entry): Metadata {
160
+ return Metadata.create({
161
+ any: false,
162
+ required: true,
163
+ optional: false,
164
+ nullable: false,
165
+ functional: false,
166
+ resolved: null,
167
+ aliases: [],
168
+ atomics: [],
169
+ constants: [],
170
+ templates: [],
171
+ rest: null,
172
+ arrays: [],
173
+ tuples: [],
174
+ objects: [],
175
+ natives: [],
176
+ sets: [],
177
+ maps: [elem],
178
+ });
179
+ }
180
+ }
@@ -0,0 +1,25 @@
1
+ import { MetadataObject } from "../../../metadata/MetadataObject";
2
+
3
+ import { IProtocolMessage } from "../../../messages/IProtocolMessage";
4
+ import { emplace_protocol_property } from "./emplace_protocol_property";
5
+
6
+ export const emplace_protocol_object =
7
+ (dict: Map<string, IProtocolMessage>) => (object: MetadataObject) => {
8
+ if (dict.has(object.name)) return;
9
+
10
+ const regular = object.properties.filter((p) => p.key.isSoleLiteral());
11
+ const dynamic = object.properties.filter((p) => !p.key.isSoleLiteral());
12
+
13
+ if (dynamic.length) return;
14
+
15
+ const output: IProtocolMessage = {
16
+ name: object.name,
17
+ properties: [],
18
+ };
19
+ dict.set(object.name, output);
20
+
21
+ output.properties.push(
22
+ ...regular.map((prop) => emplace_protocol_property(dict)(prop)),
23
+ );
24
+ return output;
25
+ };
@@ -0,0 +1,12 @@
1
+ import { MetadataProperty } from "../../../metadata/MetadataProperty";
2
+
3
+ import { IProtocolMessage } from "../../../messages/IProtocolMessage";
4
+ import { IProtocolProperty } from "../../../messages/IProtocolProperty";
5
+ import { iterate_protocol_metadata } from "./iterate_protocol_metadata";
6
+
7
+ export const emplace_protocol_property =
8
+ (dict: Map<string, IProtocolMessage>) =>
9
+ (property: MetadataProperty): IProtocolProperty => ({
10
+ key: property.key.getSoleLiteral()!,
11
+ ...iterate_protocol_metadata(dict)(property.value)(property.tags),
12
+ });
@@ -0,0 +1,34 @@
1
+ import { IMetadataTag } from "../../../metadata/IMetadataTag";
2
+
3
+ import { Atomic } from "../../../typings/Atomic";
4
+
5
+ export const iterate_protocol_atomic =
6
+ (tags: IMetadataTag[]) => (type: Atomic.Literal) => {
7
+ if (type === "boolean") return "bool";
8
+ else if (type === "number") return number(tags);
9
+ else if (type === "bigint") return bigint(tags);
10
+ else return "string";
11
+ };
12
+
13
+ const number = (tagList: IMetadataTag[]) => {
14
+ const filtered: IMetadataTag.INumberType[] = tagList.filter(
15
+ (tag) => tag.kind === "type",
16
+ ) as IMetadataTag.INumberType[];
17
+
18
+ for (const { value } of filtered)
19
+ if (value === "int") return "int32";
20
+ else if (value === "uint") return "uint32";
21
+ return "double";
22
+ };
23
+
24
+ const bigint = (tagList: IMetadataTag[]) => {
25
+ const filtered: IMetadataTag.INumberType[] = tagList.filter(
26
+ (tag) =>
27
+ tag.kind === "type" &&
28
+ (tag.value === "int64" || tag.value === "uint64"),
29
+ ) as IMetadataTag.INumberType[];
30
+
31
+ for (const { value } of filtered)
32
+ if (value === "int64" || value === "uint64") return value;
33
+ return "int64";
34
+ };
@@ -0,0 +1,27 @@
1
+ import { MetadataConstant } from "../../../metadata/MetadataConstant";
2
+
3
+ export const iterate_protocol_constant = ({
4
+ type,
5
+ values,
6
+ }: MetadataConstant) => {
7
+ if (type === "boolean") return "bool";
8
+ else if (type === "number") return number(values);
9
+ else if (type === "bigint") return bigint(values);
10
+ else return "string";
11
+ };
12
+
13
+ const bigint = (values: bigint[]): string => {
14
+ return values.every((v) => v >= BigInt(0)) ? "uint64" : "int64";
15
+ };
16
+
17
+ const number = (values: number[]): string => {
18
+ return values.some((v) => Math.floor(v) !== v)
19
+ ? "double"
20
+ : values.every((v) => v >= 0)
21
+ ? values.every((v) => v <= 2 ** 64 - 1)
22
+ ? "uint32"
23
+ : "uint64"
24
+ : values.every((v) => -(2 ** 31) <= v && v <= 2 ** 31 - 1)
25
+ ? "int32"
26
+ : "int64";
27
+ };
@@ -0,0 +1,19 @@
1
+ import { Metadata } from "../../../metadata/Metadata";
2
+
3
+ import { IProtocolMessage } from "../../../messages/IProtocolMessage";
4
+ import { ProtocolMetadataUtil } from "./ProtocolMetadataUtil";
5
+ import { emplace_protocol_object } from "./emplace_protocol_object";
6
+
7
+ export const iterate_protocol_main =
8
+ (dict: Map<string, IProtocolMessage>) =>
9
+ (meta: Metadata): string => {
10
+ // ONLY ONE OBJECT TYPE
11
+ if (ProtocolMetadataUtil.standalone(meta) && meta.objects.length === 1)
12
+ return meta.getName();
13
+
14
+ const obj = ProtocolMetadataUtil.object("__Main", dict.size);
15
+ obj.properties.push(ProtocolMetadataUtil.property("value", meta, []));
16
+ emplace_protocol_object(dict)(obj);
17
+
18
+ return obj.name;
19
+ };
@@ -0,0 +1,58 @@
1
+ import { Metadata } from "../../../metadata/Metadata";
2
+ import { MetadataObject } from "../../../metadata/MetadataObject";
3
+
4
+ import { IProtocolMap } from "../../../messages/IProtocolMap";
5
+ import { IProtocolMessage } from "../../../messages/IProtocolMessage";
6
+ import { ProtocolMetadataUtil } from "./ProtocolMetadataUtil";
7
+ import { emplace_protocol_object } from "./emplace_protocol_object";
8
+ import { iterate_protocol_atomic } from "./iterate_protocol_atomic";
9
+ import { iterate_protocol_constant } from "./iterate_protocol_constant";
10
+ import { iterate_protocol_metadata } from "./iterate_protocol_metadata";
11
+
12
+ export const iterate_protocol_map =
13
+ (sole: boolean) =>
14
+ (dict: Map<string, IProtocolMessage>) =>
15
+ (prop: Metadata.Entry): string | IProtocolMap => {
16
+ if (sole === true)
17
+ return {
18
+ type: "map",
19
+ key: getKeyName(prop.key),
20
+ value: getValueName(dict)(prop.value),
21
+ };
22
+
23
+ const obj: MetadataObject = ProtocolMetadataUtil.object(
24
+ `Map.Wrapper<${prop.key.getName()}, ${prop.value.getName()}>`,
25
+ dict.size,
26
+ );
27
+ obj.properties.push(
28
+ ProtocolMetadataUtil.property(
29
+ "value",
30
+ ProtocolMetadataUtil.map(prop),
31
+ [],
32
+ ),
33
+ );
34
+ emplace_protocol_object(dict)(obj);
35
+ return obj.name;
36
+ };
37
+
38
+ const getKeyName = (meta: Metadata) => {
39
+ for (const atomic of meta.atomics)
40
+ return iterate_protocol_atomic([])(atomic);
41
+ for (const constant of meta.constants)
42
+ return iterate_protocol_constant(constant);
43
+ return "string";
44
+ };
45
+
46
+ const getValueName =
47
+ (dict: Map<string, IProtocolMessage>) => (meta: Metadata) => {
48
+ if (ProtocolMetadataUtil.standalone(meta))
49
+ return iterate_protocol_metadata(dict)(meta)([]).oneOf[0]!.type;
50
+
51
+ const obj: MetadataObject = ProtocolMetadataUtil.object(
52
+ `Map.Value<${meta.getName()}>`,
53
+ dict.size,
54
+ );
55
+ obj.properties.push(ProtocolMetadataUtil.property("value", meta, []));
56
+ emplace_protocol_object(dict)(obj);
57
+ return obj.name;
58
+ };
@@ -0,0 +1,96 @@
1
+ import { IMetadataTag } from "../../../metadata/IMetadataTag";
2
+ import { Metadata } from "../../../metadata/Metadata";
3
+
4
+ import { IProtocolMap } from "../../../messages/IProtocolMap";
5
+ import { IProtocolMessage } from "../../../messages/IProtocolMessage";
6
+ import { IProtocolProperty } from "../../../messages/IProtocolProperty";
7
+ import { iterate_protocol_atomic } from "./iterate_protocol_atomic";
8
+ import { iterate_protocol_constant } from "./iterate_protocol_constant";
9
+ import { iterate_protocol_map } from "./iterate_protocol_map";
10
+ import { iterate_protocol_native } from "./iterate_protocol_native";
11
+ import { iterate_protocol_never } from "./iterate_protocol_never";
12
+ import { iterate_protocol_object } from "./iterate_protocol_object";
13
+ import { iterate_protocol_repeated } from "./iterate_protocol_repeated";
14
+ import { iterate_protocol_tuple } from "./iterate_protocol_tuple";
15
+
16
+ export const iterate_protocol_metadata =
17
+ (dict: Map<string, IProtocolMessage>) =>
18
+ (meta: Metadata) =>
19
+ (tags: IMetadataTag[]): Omit<IProtocolProperty, "key"> => {
20
+ // PREPARE ASSETS
21
+ const sole: boolean = meta.size() === 1;
22
+ const bucket: boolean = sole && meta.bucket() === 1;
23
+ const required: boolean =
24
+ (meta.required && !meta.nullable) ||
25
+ (sole &&
26
+ (meta.arrays.length === 1 ||
27
+ meta.sets.length === 1 ||
28
+ meta.maps.length === 1 ||
29
+ (meta.objects.length === 1 &&
30
+ meta.objects[0]!.properties.length === 1 &&
31
+ !meta.objects[0]!.properties[0]?.key.isSoleLiteral())));
32
+
33
+ const oneOf: IProtocolProperty.IOneOf[] = [];
34
+ const add = (type: string | IProtocolMap) => {
35
+ if (oneOf.some((one) => one.type === type)) return;
36
+ oneOf.push({
37
+ type,
38
+ });
39
+ };
40
+
41
+ // WHEN SINGULAR ARRAY TYPE
42
+ if (sole && meta.arrays.length + meta.sets.length === 1) {
43
+ const [container, child] =
44
+ meta.arrays.length === 1
45
+ ? (["Array", meta.arrays[0]!.value] as const)
46
+ : (["Set", meta.sets[0]!] as const);
47
+ add(
48
+ iterate_protocol_repeated(container)(true, true)(dict)(child)(
49
+ tags,
50
+ ),
51
+ );
52
+ return {
53
+ required,
54
+ oneOf,
55
+ repeated: true,
56
+ };
57
+ }
58
+
59
+ // ATOMIC TYPES
60
+ for (const type of meta.atomics)
61
+ add(iterate_protocol_atomic(tags)(type));
62
+ for (const constant of meta.constants)
63
+ add(iterate_protocol_constant(constant));
64
+ if (meta.templates.length) add("string");
65
+ if (meta.size() === 0) add(iterate_protocol_never());
66
+
67
+ // OBJECT TYPES
68
+ for (const obj of meta.objects)
69
+ add(iterate_protocol_object(sole)(dict)(obj));
70
+ for (const map of meta.maps) add(iterate_protocol_map(sole)(dict)(map));
71
+ for (const native of meta.natives)
72
+ add(iterate_protocol_native(dict)(native));
73
+
74
+ // ARRAY TYPES
75
+ for (const tuple of meta.tuples)
76
+ add(iterate_protocol_tuple(dict)(tuple.elements));
77
+ for (const array of meta.arrays)
78
+ add(
79
+ iterate_protocol_repeated("Array")(false, bucket)(dict)(
80
+ array.value,
81
+ )(tags),
82
+ );
83
+ for (const set of meta.sets)
84
+ add(
85
+ iterate_protocol_repeated("Set")(false, bucket)(dict)(set)(
86
+ tags,
87
+ ),
88
+ );
89
+
90
+ // RETURNS
91
+ return {
92
+ required,
93
+ oneOf,
94
+ repeated: false,
95
+ };
96
+ };
@@ -0,0 +1,34 @@
1
+ import { Metadata } from "../../../metadata/Metadata";
2
+
3
+ import { IProtocolMessage } from "../../../messages/IProtocolMessage";
4
+ import { ProtocolMetadataUtil } from "./ProtocolMetadataUtil";
5
+ import { emplace_protocol_object } from "./emplace_protocol_object";
6
+
7
+ export const iterate_protocol_native =
8
+ (dict: Map<string, IProtocolMessage>) => (native: string) => {
9
+ if (native === "Date") {
10
+ const obj = ProtocolMetadataUtil.object("__Timestamp", dict.size);
11
+ obj.properties.push(
12
+ ProtocolMetadataUtil.property("seconds", integer("bigint"), [
13
+ {
14
+ kind: "type",
15
+ value: "int64",
16
+ },
17
+ ]),
18
+ ProtocolMetadataUtil.property("nanos", integer("number"), [
19
+ {
20
+ kind: "type",
21
+ value: "int",
22
+ },
23
+ ]),
24
+ );
25
+ emplace_protocol_object(dict)(obj);
26
+ return "__Timestamp";
27
+ } else return "bytes";
28
+ };
29
+
30
+ const integer = (type: "number" | "bigint") => {
31
+ const meta = Metadata.initialize();
32
+ meta.atomics.push(type);
33
+ return meta;
34
+ };
@@ -0,0 +1 @@
1
+ export const iterate_protocol_never = () => "uint32";
@@ -0,0 +1,110 @@
1
+ import { Metadata } from "../../../metadata/Metadata";
2
+ import { MetadataObject } from "../../../metadata/MetadataObject";
3
+ import { MetadataProperty } from "../../../metadata/MetadataProperty";
4
+
5
+ import { Atomic } from "../../../typings/Atomic";
6
+
7
+ import { MapUtil } from "../../../utils/MapUtil";
8
+
9
+ import { IProtocolMap } from "../../../messages/IProtocolMap";
10
+ import { IProtocolMessage } from "../../../messages/IProtocolMessage";
11
+ import { ProtocolMetadataUtil } from "./ProtocolMetadataUtil";
12
+ import { emplace_protocol_object } from "./emplace_protocol_object";
13
+ import { iterate_protocol_metadata } from "./iterate_protocol_metadata";
14
+
15
+ export const iterate_protocol_object =
16
+ (sole: boolean) =>
17
+ (dict: Map<string, IProtocolMessage>) =>
18
+ (obj: MetadataObject): string | IProtocolMap => {
19
+ // ONLY REGULAR PROPERTIES
20
+ const statics: MetadataProperty[] = obj.properties.filter(filter(true));
21
+ const dynamics: Metadata.Entry[] = aggregate(
22
+ obj.properties.filter(filter(false)),
23
+ );
24
+ if (dynamics.length === 0) return obj.name;
25
+
26
+ const regular: MetadataObject | undefined = statics.length
27
+ ? (() => {
28
+ const r: MetadataObject = ProtocolMetadataUtil.object(
29
+ `${obj.name}.__Regular`,
30
+ dict.size,
31
+ );
32
+ r.properties.push(...statics);
33
+ emplace_protocol_object(dict)(r);
34
+ return r;
35
+ })()
36
+ : undefined;
37
+
38
+ // ONLY ONE TYPED DYNAMIC PROPERTY EXISTS
39
+ if (regular === undefined && dynamics.length === 1 && sole === true) {
40
+ const { key, value } = dynamics[0]!;
41
+ return {
42
+ type: "map",
43
+ key: key.getName(),
44
+ value: ProtocolMetadataUtil.standalone(value)
45
+ ? iterate_protocol_metadata(dict)(value)([]).oneOf[0]!.type
46
+ : (() => {
47
+ const wrapper = ProtocolMetadataUtil.object(
48
+ `${obj.name}.__Wrapper`,
49
+ dict.size,
50
+ );
51
+ wrapper.properties.push(
52
+ ProtocolMetadataUtil.property("value", value, []),
53
+ );
54
+ emplace_protocol_object(dict)(wrapper);
55
+ return wrapper.name;
56
+ })(),
57
+ };
58
+ }
59
+
60
+ // DO WRAP
61
+ const wrapper: MetadataObject = ProtocolMetadataUtil.object(
62
+ `${obj.name}.__Wrapper`,
63
+ dict.size,
64
+ );
65
+ if (regular !== undefined)
66
+ wrapper.properties.push(
67
+ ProtocolMetadataUtil.property(
68
+ "regular",
69
+ ProtocolMetadataUtil.reference(regular),
70
+ [],
71
+ ),
72
+ );
73
+ wrapper.properties.push(
74
+ ...dynamics.map((map, i) =>
75
+ ProtocolMetadataUtil.property(
76
+ `__map_${i}`,
77
+ ProtocolMetadataUtil.map(map),
78
+ [],
79
+ ),
80
+ ),
81
+ );
82
+ emplace_protocol_object(dict)(wrapper);
83
+ return wrapper.name;
84
+ };
85
+
86
+ const filter = (regular: boolean) => (prop: MetadataProperty) =>
87
+ regular === prop.key.isSoleLiteral();
88
+
89
+ const aggregate = (properties: MetadataProperty[]): Metadata.Entry[] => {
90
+ const unique: Map<Atomic.Literal, MetadataProperty[]> = new Map();
91
+ for (const prop of properties) {
92
+ if (prop.key.templates)
93
+ MapUtil.take(unique)("string", () => []).push(prop);
94
+ for (const type of prop.key.atomics)
95
+ MapUtil.take(unique)(type, () => []).push(prop);
96
+ for (const { type } of prop.key.constants)
97
+ MapUtil.take(unique)(type, () => []).push(prop);
98
+ }
99
+ const output: Metadata.Entry[] = [];
100
+ for (const [key, properties] of unique) {
101
+ const value: Metadata = properties
102
+ .map((x) => x.value)
103
+ .reduce((x, y) => Metadata.merge(x, y));
104
+ output.push({
105
+ key: ProtocolMetadataUtil.atomic(key),
106
+ value,
107
+ });
108
+ }
109
+ return output;
110
+ };