typia 3.6.7 → 3.7.0-dev.20230310

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 (143) hide show
  1. package/README.md +44 -15
  2. package/lib/factories/MetadataCollection.d.ts +1 -9
  3. package/lib/factories/MetadataCollection.js +2 -75
  4. package/lib/factories/MetadataCollection.js.map +1 -1
  5. package/lib/factories/ProtocolFactory.d.ts +8 -0
  6. package/lib/factories/ProtocolFactory.js +112 -0
  7. package/lib/factories/ProtocolFactory.js.map +1 -0
  8. package/lib/factories/internal/protocols/ProtocolMetadataUtil.d.ts +16 -0
  9. package/lib/factories/internal/protocols/ProtocolMetadataUtil.js +156 -0
  10. package/lib/factories/internal/protocols/ProtocolMetadataUtil.js.map +1 -0
  11. package/lib/factories/internal/protocols/emplace_protocol_object.d.ts +3 -0
  12. package/lib/factories/internal/protocols/emplace_protocol_object.js +47 -0
  13. package/lib/factories/internal/protocols/emplace_protocol_object.js.map +1 -0
  14. package/lib/factories/internal/protocols/emplace_protocol_property.d.ts +4 -0
  15. package/lib/factories/internal/protocols/emplace_protocol_property.js +20 -0
  16. package/lib/factories/internal/protocols/emplace_protocol_property.js.map +1 -0
  17. package/lib/factories/internal/protocols/iterate_protocol_atomic.d.ts +3 -0
  18. package/lib/factories/internal/protocols/iterate_protocol_atomic.js +69 -0
  19. package/lib/factories/internal/protocols/iterate_protocol_atomic.js.map +1 -0
  20. package/lib/factories/internal/protocols/iterate_protocol_constant.d.ts +2 -0
  21. package/lib/factories/internal/protocols/iterate_protocol_constant.js +30 -0
  22. package/lib/factories/internal/protocols/iterate_protocol_constant.js.map +1 -0
  23. package/lib/factories/internal/protocols/iterate_protocol_main.d.ts +3 -0
  24. package/lib/factories/internal/protocols/iterate_protocol_main.js +17 -0
  25. package/lib/factories/internal/protocols/iterate_protocol_main.js.map +1 -0
  26. package/lib/factories/internal/protocols/iterate_protocol_map.d.ts +4 -0
  27. package/lib/factories/internal/protocols/iterate_protocol_map.js +75 -0
  28. package/lib/factories/internal/protocols/iterate_protocol_map.js.map +1 -0
  29. package/lib/factories/internal/protocols/iterate_protocol_metadata.d.ts +5 -0
  30. package/lib/factories/internal/protocols/iterate_protocol_metadata.js +190 -0
  31. package/lib/factories/internal/protocols/iterate_protocol_metadata.js.map +1 -0
  32. package/lib/factories/internal/protocols/iterate_protocol_native.d.ts +2 -0
  33. package/lib/factories/internal/protocols/iterate_protocol_native.js +33 -0
  34. package/lib/factories/internal/protocols/iterate_protocol_native.js.map +1 -0
  35. package/lib/factories/internal/protocols/iterate_protocol_never.d.ts +1 -0
  36. package/lib/factories/internal/protocols/iterate_protocol_never.js +6 -0
  37. package/lib/factories/internal/protocols/iterate_protocol_never.js.map +1 -0
  38. package/lib/factories/internal/protocols/iterate_protocol_object.d.ts +4 -0
  39. package/lib/factories/internal/protocols/iterate_protocol_object.js +157 -0
  40. package/lib/factories/internal/protocols/iterate_protocol_object.js.map +1 -0
  41. package/lib/factories/internal/protocols/iterate_protocol_repeated.d.ts +5 -0
  42. package/lib/factories/internal/protocols/iterate_protocol_repeated.js +25 -0
  43. package/lib/factories/internal/protocols/iterate_protocol_repeated.js.map +1 -0
  44. package/lib/factories/internal/protocols/iterate_protocol_tuple.d.ts +3 -0
  45. package/lib/factories/internal/protocols/iterate_protocol_tuple.js +46 -0
  46. package/lib/factories/internal/protocols/iterate_protocol_tuple.js.map +1 -0
  47. package/lib/functional/$proto_bytes.d.ts +2 -0
  48. package/lib/functional/$proto_bytes.js +37 -0
  49. package/lib/functional/$proto_bytes.js.map +1 -0
  50. package/lib/functional/$proto_field.d.ts +10 -0
  51. package/lib/functional/$proto_field.js +42 -0
  52. package/lib/functional/$proto_field.js.map +1 -0
  53. package/lib/functional/$proto_float.d.ts +4 -0
  54. package/lib/functional/$proto_float.js +28 -0
  55. package/lib/functional/$proto_float.js.map +1 -0
  56. package/lib/functional/$proto_i32.d.ts +2 -0
  57. package/lib/functional/$proto_i32.js +23 -0
  58. package/lib/functional/$proto_i32.js.map +1 -0
  59. package/lib/functional/$proto_i64.d.ts +2 -0
  60. package/lib/functional/$proto_i64.js +31 -0
  61. package/lib/functional/$proto_i64.js.map +1 -0
  62. package/lib/functional/$proto_size.d.ts +6 -0
  63. package/lib/functional/$proto_size.js +76 -0
  64. package/lib/functional/$proto_size.js.map +1 -0
  65. package/lib/functional/$proto_string.d.ts +2 -0
  66. package/lib/functional/$proto_string.js +34 -0
  67. package/lib/functional/$proto_string.js.map +1 -0
  68. package/lib/functional/$varint.d.ts +6 -0
  69. package/lib/functional/$varint.js +99 -0
  70. package/lib/functional/$varint.js.map +1 -0
  71. package/lib/functional/$zigzag.d.ts +4 -0
  72. package/lib/functional/$zigzag.js +34 -0
  73. package/lib/functional/$zigzag.js.map +1 -0
  74. package/lib/messages/IProtocolMap.d.ts +5 -0
  75. package/lib/messages/IProtocolMap.js +3 -0
  76. package/lib/messages/IProtocolMap.js.map +1 -0
  77. package/lib/messages/IProtocolMessage.d.ts +5 -0
  78. package/lib/messages/IProtocolMessage.js +3 -0
  79. package/lib/messages/IProtocolMessage.js.map +1 -0
  80. package/lib/messages/IProtocolProperty.d.ts +12 -0
  81. package/lib/messages/IProtocolProperty.js +3 -0
  82. package/lib/messages/IProtocolProperty.js.map +1 -0
  83. package/lib/metadata/IMetadataTag.d.ts +7 -3
  84. package/lib/metadata/Metadata.js +2 -2
  85. package/lib/metadata/Metadata.js.map +1 -1
  86. package/lib/module.d.ts +2 -0
  87. package/lib/module.js +5 -1
  88. package/lib/module.js.map +1 -1
  89. package/lib/programmers/MessageProgrammer.d.ts +5 -0
  90. package/lib/programmers/MessageProgrammer.js +141 -0
  91. package/lib/programmers/MessageProgrammer.js.map +1 -0
  92. package/lib/programmers/internal/application_object.js +11 -11
  93. package/lib/programmers/internal/application_object.js.map +1 -1
  94. package/lib/programmers/internal/application_schema.js +5 -3
  95. package/lib/programmers/internal/application_schema.js.map +1 -1
  96. package/lib/transformers/CallExpressionTransformer.js +3 -1
  97. package/lib/transformers/CallExpressionTransformer.js.map +1 -1
  98. package/lib/transformers/features/miscellaneous/ApplicationTransformer.js +1 -3
  99. package/lib/transformers/features/miscellaneous/ApplicationTransformer.js.map +1 -1
  100. package/lib/transformers/features/protocols/MessageTransformer.d.ts +5 -0
  101. package/lib/transformers/features/protocols/MessageTransformer.js +17 -0
  102. package/lib/transformers/features/protocols/MessageTransformer.js.map +1 -0
  103. package/lib/utils/NameEncoder.d.ts +4 -0
  104. package/lib/utils/NameEncoder.js +89 -0
  105. package/lib/utils/NameEncoder.js.map +1 -0
  106. package/package.json +2 -1
  107. package/src/factories/MetadataCollection.ts +2 -41
  108. package/src/factories/ProtocolFactory.ts +79 -0
  109. package/src/factories/internal/protocols/ProtocolMetadataUtil.ts +163 -0
  110. package/src/factories/internal/protocols/emplace_protocol_object.ts +25 -0
  111. package/src/factories/internal/protocols/emplace_protocol_property.ts +12 -0
  112. package/src/factories/internal/protocols/iterate_protocol_atomic.ts +34 -0
  113. package/src/factories/internal/protocols/iterate_protocol_constant.ts +27 -0
  114. package/src/factories/internal/protocols/iterate_protocol_main.ts +19 -0
  115. package/src/factories/internal/protocols/iterate_protocol_map.ts +58 -0
  116. package/src/factories/internal/protocols/iterate_protocol_metadata.ts +96 -0
  117. package/src/factories/internal/protocols/iterate_protocol_native.ts +34 -0
  118. package/src/factories/internal/protocols/iterate_protocol_never.ts +1 -0
  119. package/src/factories/internal/protocols/iterate_protocol_object.ts +110 -0
  120. package/src/factories/internal/protocols/iterate_protocol_repeated.ts +34 -0
  121. package/src/factories/internal/protocols/iterate_protocol_tuple.ts +29 -0
  122. package/src/functional/$proto_bytes.ts +25 -0
  123. package/src/functional/$proto_field.ts +30 -0
  124. package/src/functional/$proto_float.ts +37 -0
  125. package/src/functional/$proto_i32.ts +29 -0
  126. package/src/functional/$proto_i64.ts +37 -0
  127. package/src/functional/$proto_size.ts +82 -0
  128. package/src/functional/$proto_string.ts +24 -0
  129. package/src/functional/$varint.ts +130 -0
  130. package/src/functional/$zigzag.ts +39 -0
  131. package/src/messages/IProtocolMap.ts +5 -0
  132. package/src/messages/IProtocolMessage.ts +6 -0
  133. package/src/messages/IProtocolProperty.ts +13 -0
  134. package/src/metadata/IMetadataTag.ts +20 -4
  135. package/src/metadata/Metadata.ts +6 -3
  136. package/src/module.ts +11 -0
  137. package/src/programmers/MessageProgrammer.ts +126 -0
  138. package/src/programmers/internal/application_object.ts +5 -5
  139. package/src/programmers/internal/application_schema.ts +7 -3
  140. package/src/transformers/CallExpressionTransformer.ts +16 -9
  141. package/src/transformers/features/miscellaneous/ApplicationTransformer.ts +1 -3
  142. package/src/transformers/features/protocols/MessageTransformer.ts +32 -0
  143. package/src/utils/NameEncoder.ts +32 -0
@@ -0,0 +1,82 @@
1
+ import { $proto_field_wiretype } from "./$proto_field";
2
+
3
+ export function $proto_size_varint(n: number): number;
4
+ export function $proto_size_varint(n: bigint): number;
5
+
6
+ export function $proto_size_varint(n: number | bigint): number {
7
+ if (typeof n === "number") {
8
+ if (n < 0) {
9
+ return SizeVarInt64(BigInt(n));
10
+ }
11
+ return SizeVarInt32(n);
12
+ }
13
+
14
+ return SizeVarInt64(n);
15
+ }
16
+
17
+ export function $proto_size_field(
18
+ fieldNumber: number,
19
+ wireType: $proto_field_wiretype,
20
+ ): number {
21
+ const tag = (fieldNumber << 3) | Number(wireType);
22
+ return $proto_size_varint(tag);
23
+ }
24
+
25
+ export function $proto_size_bytes(len: number): number {
26
+ return $proto_size_varint(len) + len;
27
+ }
28
+
29
+ const utf8_encoder = new TextEncoder();
30
+
31
+ export function $proto_size_string(value: string): number {
32
+ // TODO: optimize (DON'T ENCODE TEXT TWICE)
33
+ const bytes = utf8_encoder.encode(value);
34
+ return $proto_size_bytes(bytes.length);
35
+ }
36
+
37
+ function SizeVarInt32(value: number): number {
38
+ value = (value | 0) >>> 0; // 32-bit integer
39
+ // TODO: optimize ( branchless solution exists )
40
+ // TODO: try lookup table based solution
41
+
42
+ if (value <= 127) {
43
+ return 1;
44
+ } else if (value <= 16383) {
45
+ return 2;
46
+ } else if (value <= 2097151) {
47
+ return 3;
48
+ } else if (value <= 268435455) {
49
+ return 4;
50
+ }
51
+
52
+ // < 34359738367
53
+ return 5;
54
+ }
55
+
56
+ function SizeVarInt64(value: bigint): number {
57
+ value = BigInt.asUintN(64, value);
58
+ // TODO: optimize ( branchless solution exists )
59
+ // TODO: try lookup table based solution
60
+
61
+ if (value <= BigInt("127")) {
62
+ return 1;
63
+ } else if (value <= BigInt("16383")) {
64
+ return 2;
65
+ } else if (value <= BigInt("2097151")) {
66
+ return 3;
67
+ } else if (value <= BigInt("268435455")) {
68
+ return 4;
69
+ } else if (value <= BigInt("34359738367")) {
70
+ return 5;
71
+ } else if (value <= BigInt("4398046511103")) {
72
+ return 6;
73
+ } else if (value <= BigInt("562949953421311")) {
74
+ return 7;
75
+ } else if (value <= BigInt("72057594037927935")) {
76
+ return 8;
77
+ } else if (value <= BigInt("9223372036854775807")) {
78
+ return 9;
79
+ }
80
+
81
+ return 10;
82
+ }
@@ -0,0 +1,24 @@
1
+ import { $proto_bytes_decode, $proto_bytes_encode } from "./$proto_bytes";
2
+
3
+ const utf8_encoder = new TextEncoder();
4
+
5
+ export function $proto_string_encode(
6
+ dst: Uint8Array,
7
+ offset: number,
8
+ value: string,
9
+ ): number {
10
+ // TODO: optimize (DON'T ENCODE TEXT TWICE)
11
+
12
+ const bytes = utf8_encoder.encode(value);
13
+ return $proto_bytes_encode(dst, offset, bytes);
14
+ }
15
+
16
+ export function $proto_string_decode(
17
+ src: Uint8Array,
18
+ offset: number,
19
+ ): [value: string, offset: number] {
20
+ const utf8_decoder = new TextDecoder("utf-8");
21
+ const [bytes, o] = $proto_bytes_decode(src, offset);
22
+ const value = utf8_decoder.decode(bytes);
23
+ return [value, o];
24
+ }
@@ -0,0 +1,130 @@
1
+ function EncodeVarNumber(
2
+ dst: Uint8Array,
3
+ offset: number,
4
+ value: number,
5
+ ): number {
6
+ value = (value | 0) >>> 0; // 32-bit integer
7
+
8
+ while (value > 127) {
9
+ dst[offset++] = (value & 0b01111111) | 0b10000000;
10
+ value >>>= 7;
11
+ }
12
+ dst[offset++] = value;
13
+
14
+ return offset;
15
+ }
16
+
17
+ function DecodeVarNumber(
18
+ buf: Uint8Array,
19
+ offset: number,
20
+ ): [value: number, offset: number] {
21
+ let value = 0;
22
+ let shift = 0;
23
+
24
+ while (true) {
25
+ const byte = buf[offset++]!;
26
+ value |= (byte & 0b01111111) << shift;
27
+ if (byte < 128) {
28
+ break;
29
+ }
30
+ shift += 7;
31
+ }
32
+
33
+ return [value | 0, offset];
34
+ }
35
+
36
+ function DecodeVarBigInt(
37
+ buf: Uint8Array,
38
+ offset: number,
39
+ ): [value: bigint, offset: number] {
40
+ let value = BigInt(0);
41
+ let shift = BigInt(0);
42
+
43
+ while (true) {
44
+ const byte = buf[offset++]!;
45
+ value |= BigInt(byte & 0b01111111) << shift;
46
+ if (byte < 128) {
47
+ break;
48
+ }
49
+ shift += BigInt(7);
50
+ }
51
+
52
+ return [BigInt.asIntN(64, value), offset];
53
+ }
54
+
55
+ export function $varint_decode_i32(
56
+ buf: Uint8Array,
57
+ offset: number,
58
+ ): [value: number, offset: number] {
59
+ const [v, o] = DecodeVarNumber(buf, offset);
60
+ return [v, o];
61
+ }
62
+
63
+ export function $varint_decode_u32(
64
+ buf: Uint8Array,
65
+ offset: number,
66
+ ): [value: number, offset: number] {
67
+ const [v, o] = DecodeVarNumber(buf, offset);
68
+ return [v >>> 0, o];
69
+ }
70
+
71
+ export function $varint_decode_i64(
72
+ buf: Uint8Array,
73
+ offset: number,
74
+ ): [value: bigint, offset: number] {
75
+ const [v, o] = DecodeVarBigInt(buf, offset);
76
+ return [v, o];
77
+ }
78
+
79
+ export function $varint_decode_u64(
80
+ buf: Uint8Array,
81
+ offset: number,
82
+ ): [value: bigint, offset: number] {
83
+ const [v, o] = DecodeVarBigInt(buf, offset);
84
+ return [BigInt.asUintN(64, v), o];
85
+ }
86
+
87
+ function EncodeVarBigInt(
88
+ dst: Uint8Array,
89
+ offset: number,
90
+ value: bigint,
91
+ ): number {
92
+ value = BigInt.asUintN(64, value);
93
+
94
+ while (value > BigInt(127)) {
95
+ dst[offset++] = Number(value & BigInt(0b01111111)) | 0b10000000;
96
+ value >>= BigInt(7);
97
+ }
98
+ dst[offset++] = Number(value);
99
+
100
+ return offset;
101
+ }
102
+
103
+ export function $varint_encode(
104
+ dst: Uint8Array,
105
+ offset: number,
106
+ value: number,
107
+ ): number;
108
+ export function $varint_encode(
109
+ dst: Uint8Array,
110
+ offset: number,
111
+ value: bigint,
112
+ ): number;
113
+
114
+ export function $varint_encode(
115
+ dst: Uint8Array,
116
+ offset: number,
117
+ value: number | bigint,
118
+ ): number {
119
+ if (typeof value === "bigint") {
120
+ offset = EncodeVarBigInt(dst, offset, value);
121
+ } else {
122
+ if (value < 0) {
123
+ // NOTE: Protocol Buffers signed varint encoding uses two's complement of 64-bit unsigned integers.
124
+ offset = EncodeVarBigInt(dst, offset, BigInt(value));
125
+ } else {
126
+ offset = EncodeVarNumber(dst, offset, value);
127
+ }
128
+ }
129
+ return offset;
130
+ }
@@ -0,0 +1,39 @@
1
+ export function $zigzag_encode(value: number): number;
2
+ export function $zigzag_encode(value: bigint): bigint;
3
+ export function $zigzag_encode(value: number | bigint): any {
4
+ // TODO: optimize (branchless solution exists)
5
+
6
+ if (typeof value === "bigint") {
7
+ if (value < BigInt(0)) {
8
+ value = -value;
9
+ return value * BigInt(2) - BigInt(1);
10
+ }
11
+ return value * BigInt(2);
12
+ }
13
+
14
+ if (value < 0) {
15
+ value = -value;
16
+ return value * 2 - 1;
17
+ }
18
+ return value * 2;
19
+ }
20
+
21
+ export function $zigzag_decode(value: number): number;
22
+ export function $zigzag_decode(value: bigint): bigint;
23
+ export function $zigzag_decode(value: number | bigint): any {
24
+ // TODO: optimize (branchless solution exists)
25
+
26
+ if (typeof value === "bigint") {
27
+ value = BigInt.asUintN(64, value);
28
+ if (value & BigInt(1)) {
29
+ return -(value + BigInt(1)) / BigInt(2);
30
+ }
31
+ return value / BigInt(2);
32
+ }
33
+
34
+ value = value >>> 0;
35
+ if (value & 1) {
36
+ return -(value + 1) / 2;
37
+ }
38
+ return value / 2;
39
+ }
@@ -0,0 +1,5 @@
1
+ export interface IProtocolMap {
2
+ type: "map";
3
+ key: string;
4
+ value: string | IProtocolMap;
5
+ }
@@ -0,0 +1,6 @@
1
+ import { IProtocolProperty } from "./IProtocolProperty";
2
+
3
+ export interface IProtocolMessage {
4
+ name: string;
5
+ properties: IProtocolProperty[];
6
+ }
@@ -0,0 +1,13 @@
1
+ import { IProtocolMap } from "./IProtocolMap";
2
+
3
+ export interface IProtocolProperty {
4
+ key: string;
5
+ oneOf: IProtocolProperty.IOneOf[];
6
+ required: boolean;
7
+ repeated: boolean;
8
+ }
9
+ export namespace IProtocolProperty {
10
+ export interface IOneOf {
11
+ type: string | IProtocolMap;
12
+ }
13
+ }
@@ -10,13 +10,16 @@ export type IMetadataTag =
10
10
  | IMetadataTag.IMinLength
11
11
  | IMetadataTag.IMaxLength
12
12
  // NUMBER
13
- | IMetadataTag.IType
13
+ | IMetadataTag.INumberType
14
+ | IMetadataTag.IBigintType
14
15
  | IMetadataTag.IMinimum
15
16
  | IMetadataTag.IMaximum
16
17
  | IMetadataTag.IExclusiveMinimum
17
18
  | IMetadataTag.IExclusiveMaximum
18
19
  | IMetadataTag.IMultipleOf
19
- | IMetadataTag.IStep;
20
+ | IMetadataTag.IStep
21
+ // BIGINT
22
+ | IMetadataTag.IBigintType;
20
23
 
21
24
  export namespace IMetadataTag {
22
25
  /* -----------------------------------------------------------
@@ -68,9 +71,17 @@ export namespace IMetadataTag {
68
71
  /* -----------------------------------------------------------
69
72
  NUMBER
70
73
  ----------------------------------------------------------- */
71
- export interface IType {
74
+ export interface INumberType {
72
75
  kind: "type";
73
- value: "int" | "uint";
76
+ value:
77
+ | "int"
78
+ | "uint"
79
+ | "int32"
80
+ | "uint32"
81
+ | "int64"
82
+ | "uint64"
83
+ | "float"
84
+ | "double";
74
85
  }
75
86
 
76
87
  export interface IMinimum {
@@ -106,6 +117,11 @@ export namespace IMetadataTag {
106
117
  /* -----------------------------------------------------------
107
118
  MISCELLANEOUS
108
119
  ----------------------------------------------------------- */
120
+ export interface IBigintType {
121
+ kind: "type";
122
+ value: "int64" | "uint64";
123
+ }
124
+
109
125
  export interface ISign {
110
126
  include: boolean;
111
127
  value: number;
@@ -205,6 +205,7 @@ export class Metadata {
205
205
  public empty(): boolean {
206
206
  return this.bucket() === 0 || this.size() === 0;
207
207
  }
208
+
208
209
  public size(): number {
209
210
  return (
210
211
  (this.resolved ? 1 : 0) +
@@ -223,6 +224,7 @@ export class Metadata {
223
224
  this.maps.length
224
225
  );
225
226
  }
227
+
226
228
  public bucket(): number {
227
229
  return (
228
230
  (this.resolved ? 1 : 0) +
@@ -239,6 +241,7 @@ export class Metadata {
239
241
  (this.maps.length ? 1 : 0)
240
242
  );
241
243
  }
244
+
242
245
  public isConstant(): boolean {
243
246
  return this.bucket() === (this.constants.length ? 1 : 0);
244
247
  }
@@ -508,15 +511,15 @@ function getName(metadata: Metadata): string {
508
511
  elements.push(`Map<${map.key.getName()}, ${map.value.getName()}>`);
509
512
 
510
513
  // ARRAY
511
- if (metadata.rest !== null) elements.push(`...${metadata.rest.getName()}`);
514
+ if (metadata.rest !== null)
515
+ elements.push(`Rest<${metadata.rest.getName()}>`);
512
516
  for (const tuple of metadata.tuples)
513
517
  elements.push(`[${tuple.map((elem) => elem.getName()).join(", ")}]`);
514
518
  for (const array of metadata.arrays)
515
519
  elements.push(`Array<${array.getName()}>`);
516
520
 
517
521
  // OBJECT
518
- for (const object of metadata.objects)
519
- elements.push(`Resolve<${object.name}>`);
522
+ for (const object of metadata.objects) elements.push(object.name);
520
523
  if (metadata.resolved !== null) elements.push(metadata.resolved.getName());
521
524
 
522
525
  // RETURNS
package/src/module.ts CHANGED
@@ -20,6 +20,7 @@ export * from "./TypeGuardError";
20
20
  SINGLE FUNCTIONS
21
21
  - BASIC VALIDATORS
22
22
  - STRICT VALIDATORS
23
+ - PROTOCOL BUFFER FUNCTIONS
23
24
  - JSON FUNCTIONS
24
25
  - MISCELLANEOUS
25
26
  ==============================================================
@@ -410,6 +411,16 @@ export function validateEquals(): never {
410
411
  }
411
412
  Object.assign(validateEquals, Namespace.validate());
412
413
 
414
+ /* -----------------------------------------------------------
415
+ PROTOCOL BUFFER FUNCTIONS
416
+ ----------------------------------------------------------- */
417
+ export function message(): never;
418
+ export function message<T>(): string;
419
+
420
+ export function message(): string {
421
+ halt("message");
422
+ }
423
+
413
424
  /* -----------------------------------------------------------
414
425
  JSON FUNCTIONS
415
426
  ----------------------------------------------------------- */
@@ -0,0 +1,126 @@
1
+ import ts from "typescript";
2
+
3
+ import { MetadataCollection } from "../factories/MetadataCollection";
4
+ import { ProtocolFactory } from "../factories/ProtocolFactory";
5
+
6
+ import { Metadata } from "../metadata/Metadata";
7
+
8
+ import { IProject } from "../transformers/IProject";
9
+
10
+ import { Escaper } from "../utils/Escaper";
11
+ import { MapUtil } from "../utils/MapUtil";
12
+ import { NameEncoder } from "../utils/NameEncoder";
13
+
14
+ import { IProtocolMap } from "../messages/IProtocolMap";
15
+ import { IProtocolMessage } from "../messages/IProtocolMessage";
16
+
17
+ export namespace MessageProgrammer {
18
+ export const generate =
19
+ ({ checker }: IProject) =>
20
+ (type: ts.Type) => {
21
+ // PARSE TARGET TYPE
22
+ const collection: MetadataCollection = new MetadataCollection();
23
+ const metadata: Metadata =
24
+ ProtocolFactory.metadata(checker)(collection)(type);
25
+
26
+ // CONVERT TO PROTOCOL MESSAGES
27
+ const dict: Map<string, IProtocolMessage> = new Map();
28
+ ProtocolFactory.generate(collection)(dict)(metadata);
29
+
30
+ // STRINGIFY
31
+ const hierarchies: Map<string, Hierarchy> = new Map();
32
+ for (const msg of dict.values()) emplace(hierarchies)(msg);
33
+
34
+ const content: string =
35
+ `syntax = "proto3";\n\n` +
36
+ [...hierarchies.values()]
37
+ .map((hier) => stringify(hier))
38
+ .join("\n\n");
39
+
40
+ // RETURNS
41
+ return ts.factory.createStringLiteral(content);
42
+ };
43
+
44
+ const stringify = (hierarchy: Hierarchy): string => {
45
+ const { key, message, children } = hierarchy;
46
+ let index: number = 1;
47
+
48
+ const elements: string[] = [`message ${NameEncoder.encode(key)} {`];
49
+ if (message !== null)
50
+ elements.push(
51
+ ...message.properties.map((property) => {
52
+ const key: string =
53
+ Escaper.variable(property.key) &&
54
+ property.key.indexOf("$") === -1
55
+ ? property.key
56
+ : `v${index + 1}`;
57
+ if (property.oneOf.length === 1)
58
+ return [
59
+ TAB,
60
+ property.required ? "" : "optional ",
61
+ property.repeated ? "repeated " : "",
62
+ getTypeName(property.oneOf[0]!.type) + " ",
63
+ key,
64
+ " = ",
65
+ `${index++};`,
66
+ ].join("");
67
+ return (
68
+ `${TAB}oneof ${key} {\n` +
69
+ property.oneOf
70
+ .map(
71
+ (o, i) =>
72
+ `${TAB}${TAB}${getTypeName(
73
+ o.type,
74
+ )} ${key}_o${i} = ${index++};`,
75
+ )
76
+ .join("\n") +
77
+ `\n${TAB}}`
78
+ );
79
+ }),
80
+ );
81
+ if (message !== null && children.size) elements.push("\n");
82
+ if (children.size)
83
+ elements.push(
84
+ [...children.values()]
85
+ .map((child) => stringify(child))
86
+ .map((body) =>
87
+ body
88
+ .split("\n")
89
+ .map((line) => `${TAB}${line}`)
90
+ .join("\n"),
91
+ )
92
+ .join("\n\n"),
93
+ );
94
+ elements.push("}");
95
+
96
+ return elements.join("\n");
97
+ };
98
+
99
+ const emplace =
100
+ (dict: Map<string, Hierarchy>) => (message: IProtocolMessage) => {
101
+ const accessors: string[] = message.name.split(".");
102
+ accessors.forEach((access, i) => {
103
+ const hierarchy: Hierarchy = MapUtil.take(dict, access, () => ({
104
+ key: access,
105
+ message: null!,
106
+ children: new Map(),
107
+ }));
108
+ dict = hierarchy.children;
109
+ if (i === accessors.length - 1) hierarchy.message = message;
110
+ });
111
+ };
112
+
113
+ function getTypeName(type: string | IProtocolMap): string {
114
+ return typeof type === "string"
115
+ ? NameEncoder.encode(type)
116
+ : `map<${type.key}, ${getTypeName(type.value)}>`;
117
+ }
118
+ }
119
+
120
+ interface Hierarchy {
121
+ key: string;
122
+ message: IProtocolMessage | null;
123
+ children: Map<string, Hierarchy>;
124
+ }
125
+
126
+ const TAB = " ".repeat(4);
@@ -18,10 +18,10 @@ import { metadata_to_pattern } from "./metadata_to_pattern";
18
18
  export const application_object =
19
19
  (options: ApplicationProgrammer.IOptions) =>
20
20
  (components: IJsonComponents) =>
21
- (key: string, obj: MetadataObject, nullable: boolean): void => {
21
+ (id: string, obj: MetadataObject, nullable: boolean): void => {
22
22
  // TEMPORARY ASSIGNMENT
23
- if (components.schemas[key] !== undefined) return;
24
- components.schemas[key] = {} as any;
23
+ if (components.schemas[id] !== undefined) return;
24
+ components.schemas[id] = {} as any;
25
25
 
26
26
  // ITERATE PROPERTIES
27
27
  const properties: Record<string, any> = {};
@@ -97,7 +97,7 @@ export const application_object =
97
97
  const schema: IJsonComponents.IObject = {
98
98
  $id:
99
99
  options.purpose === "ajv"
100
- ? options.prefix + "/" + key
100
+ ? options.prefix + "/" + id
101
101
  : undefined,
102
102
  $recursiveAnchor:
103
103
  (options.purpose === "ajv" && obj.recursive) || undefined,
@@ -118,7 +118,7 @@ export const application_object =
118
118
  join(options)(components)(extraMeta),
119
119
  }),
120
120
  };
121
- components.schemas[key] = schema;
121
+ components.schemas[id] = schema;
122
122
  };
123
123
 
124
124
  const join =
@@ -2,6 +2,8 @@ import { Metadata } from "../../metadata/Metadata";
2
2
  import { IJsonComponents } from "../../schemas/IJsonComponents";
3
3
  import { IJsonSchema } from "../../schemas/IJsonSchema";
4
4
 
5
+ import { NameEncoder } from "../../utils/NameEncoder";
6
+
5
7
  import { ApplicationProgrammer } from "../ApplicationProgrammer";
6
8
  import { AtomicPredicator } from "../helpers/AtomicPredicator";
7
9
  import { application_array } from "./application_array";
@@ -142,12 +144,14 @@ export const application_schema =
142
144
 
143
145
  // OBJECT
144
146
  for (const obj of meta.objects) {
145
- const key: string = obj.name + (meta.nullable ? ".Nullable" : "");
146
- application_object(options)(components)(key, obj, meta.nullable);
147
+ const id: string =
148
+ NameEncoder.encode(obj.name) +
149
+ (meta.nullable ? ".Nullable" : "");
150
+ application_object(options)(components)(id, obj, meta.nullable);
147
151
  union.push(
148
152
  (options.purpose === "ajv" && obj.recursive
149
153
  ? recursive
150
- : reference)(`${options.prefix}/${key}`, attribute),
154
+ : reference)(`${options.prefix}/${id}`, attribute),
151
155
  );
152
156
  }
153
157
 
@@ -28,6 +28,7 @@ import { CreateIsParseTransformer } from "./features/parsers/CreateIsParseTransf
28
28
  import { CreateValidateParseTransformer } from "./features/parsers/CreateValidateParseTransformer";
29
29
  import { IsParseTransformer } from "./features/parsers/IsParseTransformer";
30
30
  import { ValidateParseTransformer } from "./features/parsers/ValidateParseTransformer";
31
+ import { MessageTransformer } from "./features/protocols/MessageTransformer";
31
32
  import { AssertStringifyTransformer } from "./features/stringifiers/AssertStringifyTransformer";
32
33
  import { CreateAssertStringifyTransformer } from "./features/stringifiers/CreateAssertStringifyTransformer";
33
34
  import { CreateIsStringifyTransformer } from "./features/stringifiers/CreateIsStringifyTransformer";
@@ -94,7 +95,7 @@ const CLI_PATH = path.resolve(
94
95
 
95
96
  const FUNCTORS: Record<string, () => Task> = {
96
97
  //----
97
- // SINGLE FUNCTIONS
98
+ // VALIDATORS
98
99
  //----
99
100
  // BASIC VALIDATORS
100
101
  assert: () => AssertTransformer.transform(false),
@@ -107,13 +108,23 @@ const FUNCTORS: Record<string, () => Task> = {
107
108
  equals: () => IsTransformer.transform(true),
108
109
  validateEquals: () => ValidateTransformer.transform(true),
109
110
 
110
- // PARSE FUNCTIONS
111
+ //----
112
+ // PROTOCOL BUFFER
113
+ //----
114
+ message: () => MessageTransformer.transform,
115
+
116
+ //----
117
+ // JSON FUNCTIONS
118
+ //----
119
+ // SCHEMA DEFINITION
120
+ application: () => ApplicationTransformer.transform,
121
+
122
+ // PARSER FUNCTIONS
111
123
  isParse: () => IsParseTransformer.transform,
112
124
  assertParse: () => AssertParseTransformer.transform,
113
125
  validateParse: () => ValidateParseTransformer.transform,
114
126
 
115
127
  // STRINGIFY FUNCTIONS
116
- application: () => ApplicationTransformer.transform,
117
128
  stringify: () => StringifyTransformer.transform,
118
129
  assertStringify: () => AssertStringifyTransformer.transform,
119
130
  isStringify: () => IsStringifyTransformer.transform,
@@ -136,23 +147,19 @@ const FUNCTORS: Record<string, () => Task> = {
136
147
  //----
137
148
  // FACTORY FUNCTIONS
138
149
  //----
139
- // BASIC VALIDATORS
150
+ // VALIDATORS
140
151
  createAssert: () => CreateAssertTransformer.transform(false),
141
152
  createAssertType: () => CreateAssertTransformer.transform(false),
142
153
  createIs: () => CreateIsTransformer.transform(false),
143
154
  createValidate: () => CreateValidateTransformer.transform(false),
144
-
145
- // STRICT VALIDATORS
146
155
  createAssertEquals: () => CreateAssertTransformer.transform(true),
147
156
  createEquals: () => CreateIsTransformer.transform(true),
148
157
  createValidateEquals: () => CreateValidateTransformer.transform(true),
149
158
 
150
- // PARSE FUNCTIONS
159
+ // JSON FUNCTIONS
151
160
  createIsParse: () => CreateIsParseTransformer.transform,
152
161
  createAssertParse: () => CreateAssertParseTransformer.transform,
153
162
  createValidateParse: () => CreateValidateParseTransformer.transform,
154
-
155
- // STRINGIFY FUNCTIONS
156
163
  createStringify: () => CreateStringifyTransformer.transform,
157
164
  createAssertStringify: () => CreateAssertStringifyTransformer.transform,
158
165
  createIsStringify: () => CreateIsStringifyTransformer.transform,