• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef LIBABCKIT_STD_METADATA_INSPECT_IMPL_H
17 #define LIBABCKIT_STD_METADATA_INSPECT_IMPL_H
18 
19 #include "libabckit/src/include_v2/c/isa/field.h"
20 #include "libabckit/include/c/metadata_core.h"
21 #include <cstdint>
22 #include <variant>
23 #include <vector>
24 #include <unordered_map>
25 #include <string>
26 #include <memory>
27 
28 namespace panda::pandasm {
29 struct Program;
30 struct Function;
31 struct Record;
32 struct LiteralArray;
33 }  // namespace panda::pandasm
34 namespace ark::pandasm {
35 struct Function;
36 struct Program;
37 struct Record;
38 struct LiteralArray;
39 }  // namespace ark::pandasm
40 
41 namespace libabckit {
42 
43 enum class Mode {
44     DYNAMIC,
45     STATIC,
46 };
47 
48 struct pandasm_Literal;
49 struct pandasm_Value;
50 
51 }  // namespace libabckit
52 
53 /* ====================
54  * Internal implementations for all of the Abckit* structures
55  */
56 
57 /*
58  * NOTE: after v1 releases, move this enum to the user headers, add static types
59  * NOTE: come up with a better name
60  */
61 enum AbckitImportExportDescriptorKind {
62     UNTYPED,  // Applies to: JavaScript
63 };
64 
65 enum AbckitDynamicExportKind {
66     ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT,
67     ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT,
68     ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT,
69 };
70 
71 // NOLINTBEGIN(misc-non-private-member-variables-in-classes)
72 using AbckitValueImplT = std::unique_ptr<libabckit::pandasm_Value, void (*)(libabckit::pandasm_Value *)>;
73 struct AbckitValue {
74     AbckitFile *file = nullptr;
75     /*
76      * Underlying implementation
77      */
78     AbckitValueImplT val;
AbckitValueAbckitValue79     AbckitValue(AbckitFile *file, AbckitValueImplT val) : file(file), val(std::move(val)) {}
80 };
81 
82 struct AbckitArktsAnnotationInterface {
83     /*
84      * Points to the pandasm::Record that stores annotation definition.
85      */
86     std::variant<panda::pandasm::Record *, ark::pandasm::Record *> impl;
87 
GetStaticImplAbckitArktsAnnotationInterface88     ark::pandasm::Record *GetStaticImpl()
89     {
90         return std::get<ark::pandasm::Record *>(impl);
91     }
92 
GetDynamicImplAbckitArktsAnnotationInterface93     panda::pandasm::Record *GetDynamicImpl()
94     {
95         return std::get<panda::pandasm::Record *>(impl);
96     }
97 
98     AbckitCoreAnnotationInterface *core = nullptr;
99 };
100 
101 struct AbckitCoreAnnotationInterface {
102     /*
103      * To refer to the properties of the origin module.
104      */
105     AbckitCoreModule *owningModule = nullptr;
106 
107     /*
108      * Contains annotation interface fields
109      */
110     std::vector<std::unique_ptr<AbckitCoreAnnotationInterfaceField>> fields;
111 
112     std::variant<std::unique_ptr<AbckitArktsAnnotationInterface>> impl;
GetArkTSImplAbckitCoreAnnotationInterface113     AbckitArktsAnnotationInterface *GetArkTSImpl()
114     {
115         return std::get<std::unique_ptr<AbckitArktsAnnotationInterface>>(impl).get();
116     }
117 };
118 
119 struct AbckitArktsAnnotationInterfaceField {
120     AbckitCoreAnnotationInterfaceField *core = nullptr;
121 };
122 
123 struct AbckitCoreAnnotationInterfaceField {
124     /*
125      * To refer to the properties of the origin annotation interface.
126      */
127     AbckitCoreAnnotationInterface *ai = nullptr;
128 
129     /*
130      * Field name
131      */
132     AbckitString *name = nullptr;
133 
134     /*
135      * Field type
136      */
137     AbckitType *type = nullptr;
138 
139     /*
140      * Field value
141      */
142     AbckitValue *value = nullptr;
143 
144     std::variant<std::unique_ptr<AbckitArktsAnnotationInterfaceField>> impl;
GetArkTSImplAbckitCoreAnnotationInterfaceField145     AbckitArktsAnnotationInterfaceField *GetArkTSImpl()
146     {
147         return std::get<std::unique_ptr<AbckitArktsAnnotationInterfaceField>>(impl).get();
148     }
149 };
150 
151 struct AbckitArktsAnnotationElement {
152     AbckitCoreAnnotationElement *core = nullptr;
153 };
154 
155 struct AbckitCoreAnnotationElement {
156     /*
157      * To refer to the properties of the origin annotation.
158      */
159     AbckitCoreAnnotation *ann = nullptr;
160 
161     /*
162      * Name of annotation element
163      */
164     AbckitString *name = nullptr;
165 
166     /*
167      * Value stored in annotation
168      */
169     AbckitValue *value = nullptr;
170 
171     std::variant<std::unique_ptr<AbckitArktsAnnotationElement>> impl;
GetArkTSImplAbckitCoreAnnotationElement172     AbckitArktsAnnotationElement *GetArkTSImpl()
173     {
174         return std::get<std::unique_ptr<AbckitArktsAnnotationElement>>(impl).get();
175     }
176 };
177 
178 struct AbckitArktsAnnotation {
179     AbckitCoreAnnotation *core = nullptr;
180 };
181 
182 struct AbckitCoreAnnotation {
183     /*
184      * To refer to the properties of the annotation interface
185      */
186     AbckitCoreAnnotationInterface *ai = nullptr;
187 
188     /*
189      * To refer to the properties of the owner.
190      */
191     std::variant<AbckitCoreClass *, AbckitCoreFunction *> owner;
192 
193     /*
194      * Name of the annotation
195      */
196     AbckitString *name = nullptr;
197 
198     /*
199      * Annotation elements
200      */
201     std::vector<std::unique_ptr<AbckitCoreAnnotationElement>> elements;
202 
203     std::variant<std::unique_ptr<AbckitArktsAnnotation>> impl;
GetArkTSImplAbckitCoreAnnotation204     AbckitArktsAnnotation *GetArkTSImpl()
205     {
206         return std::get<std::unique_ptr<AbckitArktsAnnotation>>(impl).get();
207     }
208 };
209 
210 struct AbckitArktsClassPayload {
211     /*
212      * In Arkts1 class is defined by it's constructor.
213      * In Arkts2 class is defined by corresponding pandasm::Record.
214      */
215     std::variant<panda::pandasm::Function *, ark::pandasm::Record *> cl;
216 
GetStaticClassAbckitArktsClassPayload217     ark::pandasm::Record *GetStaticClass()
218     {
219         return std::get<ark::pandasm::Record *>(cl);
220     }
GetDynamicClassAbckitArktsClassPayload221     panda::pandasm::Function *GetDynamicClass()
222     {
223         return std::get<panda::pandasm::Function *>(cl);
224     }
225 };
226 
227 struct AbckitArktsClass {
228     AbckitArktsClassPayload impl;
229     AbckitCoreClass *core = nullptr;
230 
AbckitArktsClassAbckitArktsClass231     explicit AbckitArktsClass(panda::pandasm::Function *function)
232     {
233         impl.cl = reinterpret_cast<panda::pandasm::Function *>(function);
234     };
235 
AbckitArktsClassAbckitArktsClass236     explicit AbckitArktsClass(ark::pandasm::Record *record)
237     {
238         impl.cl = reinterpret_cast<ark::pandasm::Record *>(record);
239     };
240 };
241 
242 struct AbckitJsClass {
243     panda::pandasm::Function *impl;
244     AbckitCoreClass *core = nullptr;
245 
AbckitJsClassAbckitJsClass246     explicit AbckitJsClass(panda::pandasm::Function *function)
247     {
248         impl = reinterpret_cast<panda::pandasm::Function *>(function);
249     };
250 };
251 
252 struct AbckitCoreClass {
253     /*
254      * To refer to the properties of the origin module.
255      */
256     AbckitCoreModule *owningModule = nullptr;
257 
258     /*
259      * To refer to the properties of the parent namepsace.
260      */
261     AbckitCoreNamespace *parentNamespace = nullptr;
262 
263     /*
264      * To refer to the properties of the parent function.
265      */
266     AbckitCoreFunction *parentFunction = nullptr;
267 
268     /*
269      * To store class methods.
270      */
271     std::vector<std::unique_ptr<AbckitCoreFunction>> methods {};
272 
273     /*
274      * To store links to the wrapped annotations.
275      */
276     std::vector<std::unique_ptr<AbckitCoreAnnotation>> annotations;
277 
278     /*
279      * Language-dependent implementation to store class data.
280      */
281     std::variant<std::unique_ptr<AbckitJsClass>, std::unique_ptr<AbckitArktsClass>> impl;
GetArkTSImplAbckitCoreClass282     AbckitArktsClass *GetArkTSImpl()
283     {
284         return std::get<std::unique_ptr<AbckitArktsClass>>(impl).get();
285     }
GetJsImplAbckitCoreClass286     AbckitJsClass *GetJsImpl()
287     {
288         return std::get<std::unique_ptr<AbckitJsClass>>(impl).get();
289     }
290 
AbckitCoreClassAbckitCoreClass291     AbckitCoreClass(AbckitCoreModule *module, AbckitJsClass klass)
292     {
293         klass.core = this;
294         impl = std::make_unique<AbckitJsClass>(klass);
295         owningModule = module;
296     }
AbckitCoreClassAbckitCoreClass297     AbckitCoreClass(AbckitCoreModule *module, AbckitArktsClass klass)
298     {
299         klass.core = this;
300         impl = std::make_unique<AbckitArktsClass>(klass);
301         owningModule = module;
302     }
303 };
304 
305 struct AbckitJsFunction {
306     AbckitCoreFunction *core = nullptr;
307     panda::pandasm::Function *impl = nullptr;
308 };
309 
310 struct AbckitArktsFunction {
311     std::variant<panda::pandasm::Function *, ark::pandasm::Function *> impl;
312 
GetStaticImplAbckitArktsFunction313     ark::pandasm::Function *GetStaticImpl()
314     {
315         return std::get<ark::pandasm::Function *>(impl);
316     }
GetDynamicImplAbckitArktsFunction317     panda::pandasm::Function *GetDynamicImpl()
318     {
319         return std::get<panda::pandasm::Function *>(impl);
320     }
321 
322     AbckitCoreFunction *core = nullptr;
323 };
324 
325 struct AbckitCoreFunction {
326     /*
327      * To refer to the properties of the origin module.
328      */
329     AbckitCoreModule *owningModule = nullptr;
330 
331     /*
332      * To refer to the properties of the parent namepsace.
333      */
334     AbckitCoreNamespace *parentNamespace = nullptr;
335 
336     /*
337      * To be able to refer to the class where method is defined.
338      * For global functions the rules are as follows:
339      * - Dynamic: pandasm::Function with js file name.
340      * - Static: pandasm::Record with name `L/.../ETSGLOBAL`.
341      */
342     AbckitCoreClass *parentClass = nullptr;
343 
344     /*
345      * To be able to refer to the class where method is defined.
346      */
347     AbckitCoreFunction *parentFunction = nullptr;
348 
349     /*
350      * To store links to the wrapped annotations.
351      */
352     std::vector<std::unique_ptr<AbckitCoreAnnotation>> annotations;
353 
354     std::vector<std::unique_ptr<AbckitCoreFunction>> nestedFunction;
355     std::vector<std::unique_ptr<AbckitCoreClass>> nestedClasses;
356 
357     bool isAnonymous = false;
358 
359     std::variant<std::unique_ptr<AbckitJsFunction>, std::unique_ptr<AbckitArktsFunction>> impl;
360 
GetArkTSImplAbckitCoreFunction361     AbckitArktsFunction *GetArkTSImpl()
362     {
363         return std::get<std::unique_ptr<AbckitArktsFunction>>(impl).get();
364     }
GetJsImplAbckitCoreFunction365     AbckitJsFunction *GetJsImpl()
366     {
367         return std::get<std::unique_ptr<AbckitJsFunction>>(impl).get();
368     }
369 };
370 
371 struct AbckitArktsNamespace {
372     AbckitCoreNamespace *core = nullptr;
373     /*
374      * To store links to the wrapped methods.
375      */
376     std::unique_ptr<AbckitCoreFunction> f;
377 };
378 
379 struct AbckitCoreNamespace {
AbckitCoreNamespaceAbckitCoreNamespace380     explicit AbckitCoreNamespace(AbckitCoreModule *owningModule) : owningModule(owningModule) {}
381 
382     /*
383      * To refer to the properties of the origin module.
384      */
385     AbckitCoreModule *owningModule = nullptr;
386 
387     /*
388      * To be able to refer to the namespace where method is defined.
389      */
390     AbckitCoreNamespace *parentNamespace = nullptr;
391 
392     /*
393      * To store links to the wrapped methods.
394      */
395     std::vector<std::unique_ptr<AbckitCoreFunction>> functions;
396 
397     /*
398      * To store links to the wrapped classes.
399      */
400     std::vector<std::unique_ptr<AbckitCoreClass>> classes;
401     /*
402      * To store links to the wrapped namespaces.
403      */
404     std::vector<std::unique_ptr<AbckitCoreNamespace>> namespaces;
405 
406     std::variant<std::unique_ptr<AbckitArktsNamespace>> impl;
407 
GetArkTSImplAbckitCoreNamespace408     AbckitArktsNamespace *GetArkTSImpl()
409     {
410         return std::get<std::unique_ptr<AbckitArktsNamespace>>(impl).get();
411     }
412 };
413 
414 struct AbckitModulePayloadDyn {
415     /*
416      * In JS module is defined by corresponding pandasm::Record and AbckitLiteralArray.
417      */
418     const panda::pandasm::Record *record = nullptr;
419     AbckitLiteralArray *moduleLiteralArray = nullptr;
420     AbckitLiteralArray *scopeNamesLiteralArray = nullptr;
421     bool absPaths = false;
422     size_t moduleRequestsOffset = 0;
423     size_t regularImportsOffset = 0;
424     size_t namespaceImportsOffset = 0;
425     size_t localExportsOffset = 0;
426     size_t indirectExportsOffset = 0;
427     size_t starExportsOffset = 0;
428 };
429 
430 struct AbckitModulePayload {
431     /*
432      * Some data structure for STS which should store module's name and other data.
433      */
434     std::variant<AbckitModulePayloadDyn> impl;
435     /*
436      * Implementation for JS.
437      */
GetDynModuleAbckitModulePayload438     AbckitModulePayloadDyn &GetDynModule()
439     {
440         return std::get<AbckitModulePayloadDyn>(impl);
441     }
442 };
443 
444 struct AbckitArktsModule {
445     AbckitModulePayload impl;
446     AbckitCoreModule *core = nullptr;
447 };
448 
449 struct AbckitJsModule {
450     AbckitModulePayloadDyn impl {};
451     AbckitCoreModule *core = nullptr;
452 };
453 
454 struct AbckitCoreModule {
455     /*
456      * To refer to the properties of the original `.abc` file, such as is it dynamic, etc.
457      */
458     AbckitFile *file = nullptr;
459 
460     /*
461      * Stores module's dependencies.
462      * NOTE: For JS index here must match the index in `module_requests`.
463      */
464     std::vector<AbckitCoreModule *> md;
465 
466     /*
467      * Stores module's imports.
468      * NOTE: For JS will need to perform linear search to find needed import,
469      * because namespace imports and regular imports are stored together here.
470      */
471     std::vector<std::unique_ptr<AbckitCoreImportDescriptor>> id;
472 
473     /*
474      * Stores module's exports.
475      * NOTE: For JS will need to perform linear search to find needed import,
476      * because local exports, indirect exports and star exports are stored together here.
477      */
478     std::vector<std::unique_ptr<AbckitCoreExportDescriptor>> ed;
479 
480     /*
481      * Tables to store and find wrapped entities by their name.
482      */
483     std::unordered_map<std::string, std::unique_ptr<AbckitCoreClass>> ct;
484     std::unordered_map<std::string, std::unique_ptr<AbckitCoreAnnotationInterface>> at;
485     std::vector<std::unique_ptr<AbckitCoreNamespace>> namespaces;
486 
487     /*
488      * Only stores top level functions.
489      */
490     std::vector<std::unique_ptr<AbckitCoreFunction>> functions;
491 
492     /*
493      * Current module's name.
494      */
495     AbckitString *moduleName = nullptr;
496 
497     /*
498      * Indicator whether current module is local or external.
499      */
500     bool isExternal = false;
501 
502     /*
503      * Target language of current module
504      */
505     AbckitTarget target = ABCKIT_TARGET_UNKNOWN;
506 
507     /*
508      * Language-dependent implementation to store module data.
509      */
510     std::variant<std::unique_ptr<AbckitJsModule>, std::unique_ptr<AbckitArktsModule>> impl;
GetArkTSImplAbckitCoreModule511     AbckitArktsModule *GetArkTSImpl()
512     {
513         return std::get<std::unique_ptr<AbckitArktsModule>>(impl).get();
514     }
GetJsImplAbckitCoreModule515     AbckitJsModule *GetJsImpl()
516     {
517         return std::get<std::unique_ptr<AbckitJsModule>>(impl).get();
518     }
519 
InsertClassAbckitCoreModule520     void InsertClass(const std::string &name, std::unique_ptr<AbckitCoreClass> &&klass)
521     {
522         ct.emplace(name, std::move(klass));
523     }
524 };
525 
526 struct AbckitString {
527     std::string_view impl;
528 };
529 
530 using AbckitLiteralImplT = std::unique_ptr<libabckit::pandasm_Literal, void (*)(libabckit::pandasm_Literal *)>;
531 struct AbckitLiteral {
AbckitLiteralAbckitLiteral532     AbckitLiteral(AbckitFile *file, AbckitLiteralImplT val) : file(file), val(std::move(val)) {}
533     AbckitFile *file;
534     AbckitLiteralImplT val;
535 };
536 
537 struct AbckitLiteralArray {
538     AbckitFile *file = nullptr;
539     std::variant<ark::pandasm::LiteralArray *, panda::pandasm::LiteralArray *> impl;
540 
541     AbckitLiteralArray() = default;
542 
AbckitLiteralArrayAbckitLiteralArray543     AbckitLiteralArray(AbckitFile *f, ark::pandasm::LiteralArray *laImpl)
544     {
545         impl = laImpl;
546         file = f;
547     }
548 
AbckitLiteralArrayAbckitLiteralArray549     AbckitLiteralArray(AbckitFile *f, panda::pandasm::LiteralArray *laImpl)
550     {
551         impl = laImpl;
552         file = f;
553     }
554 
GetStaticImplAbckitLiteralArray555     ark::pandasm::LiteralArray *GetStaticImpl() const
556     {
557         return std::get<ark::pandasm::LiteralArray *>(impl);
558     }
GetDynamicImplAbckitLiteralArray559     panda::pandasm::LiteralArray *GetDynamicImpl() const
560     {
561         return std::get<panda::pandasm::LiteralArray *>(impl);
562     }
563 };
564 
565 struct AbckitType {
566     AbckitTypeId id = ABCKIT_TYPE_ID_INVALID;
567     size_t rank = 0;
568     AbckitCoreClass *klass = nullptr;
569 };
570 
571 struct AbckitFile {
572     struct AbcKitLiterals {
573         std::unordered_map<bool, std::unique_ptr<AbckitLiteral>> boolLits;
574         std::unordered_map<uint8_t, std::unique_ptr<AbckitLiteral>> u8Lits;
575         std::unordered_map<uint16_t, std::unique_ptr<AbckitLiteral>> u16Lits;
576         std::unordered_map<uint16_t, std::unique_ptr<AbckitLiteral>> methodAffilateLits;
577         std::unordered_map<uint32_t, std::unique_ptr<AbckitLiteral>> u32Lits;
578         std::unordered_map<uint64_t, std::unique_ptr<AbckitLiteral>> u64Lits;
579         std::unordered_map<float, std::unique_ptr<AbckitLiteral>> floatLits;
580         std::unordered_map<double, std::unique_ptr<AbckitLiteral>> doubleLits;
581         std::unordered_map<std::string, std::unique_ptr<AbckitLiteral>> litArrLits;
582         std::unordered_map<std::string, std::unique_ptr<AbckitLiteral>> stringLits;
583         std::unordered_map<std::string, std::unique_ptr<AbckitLiteral>> methodLits;
584     };
585     struct AbcKitValues {
586         std::unordered_map<bool, std::unique_ptr<AbckitValue>> boolVals;
587         std::unordered_map<double, std::unique_ptr<AbckitValue>> doubleVals;
588         std::unordered_map<std::string, std::unique_ptr<AbckitValue>> stringVals;
589         std::unordered_map<std::string, std::unique_ptr<AbckitValue>> litarrVals;
590     };
591 
592     libabckit::Mode frontend = libabckit::Mode::DYNAMIC;
593 
594     /*
595      * Table to store wrapped internal modules.
596      */
597     std::unordered_map<std::string, std::unique_ptr<AbckitCoreModule>> localModules;
598 
599     /*
600      * Table to store wrapped external modules.
601      */
602     std::unordered_map<std::string, std::unique_ptr<AbckitCoreModule>> externalModules;
603 
604     /*
605      * To store the original program and update it.
606      */
607     std::variant<panda::pandasm::Program *, ark::pandasm::Program *> program;
608 
GetStaticProgramAbckitFile609     ark::pandasm::Program *GetStaticProgram()
610     {
611         return std::get<ark::pandasm::Program *>(program);
612     }
GetDynamicProgramAbckitFile613     panda::pandasm::Program *GetDynamicProgram()
614     {
615         return std::get<panda::pandasm::Program *>(program);
616     }
617 
618     AbcKitLiterals literals;
619     std::unordered_map<size_t, std::unique_ptr<AbckitType>> types;
620     AbcKitValues values;
621     std::vector<std::unique_ptr<AbckitLiteralArray>> litarrs;
622 
623     /*
624      * To store all program strings
625      */
626     std::unordered_map<std::string, std::unique_ptr<AbckitString>> strings;
627 
628     std::unordered_map<std::string, AbckitCoreFunction *> nameToFunction;
629 
630     /*
631      * To store the .abc file version
632      */
633     AbckitFileVersion version = nullptr;
634 
635     void *internal = nullptr;
636 };
637 
638 struct AbckitDynamicImportDescriptorPayload {
639     /*
640      * Indicator whether import is namespace or regular.
641      */
642     bool isRegularImport = false;
643     /*
644      * Offset in the corresponding `XXX_imports` in mainline.
645      */
646     uint32_t moduleRecordIndexOff = 0;
647 };
648 
649 struct AbckitStaticImportDescriptorPayload {
650     std::variant<AbckitCoreAnnotationInterface *, AbckitCoreClass *, AbckitCoreFunction *, AbckitCoreField *> impl;
651     /*
652      * Implementation for AbckitImportExportDescriptorKind::ANNOTATION.
653      */
GetAnnotationInterfacePayloadAbckitStaticImportDescriptorPayload654     AbckitCoreAnnotationInterface *GetAnnotationInterfacePayload()
655     {
656         return std::get<AbckitCoreAnnotationInterface *>(impl);
657     }
658     /*
659      * Implementation for AbckitImportExportDescriptorKind::CLASS.
660      */
GetClassPayloadAbckitStaticImportDescriptorPayload661     AbckitCoreClass *GetClassPayload()
662     {
663         return std::get<AbckitCoreClass *>(impl);
664     }
665     /*
666      * Implementation for AbckitImportExportDescriptorKind::FUNCTION.
667      */
GetFunctionPayloadAbckitStaticImportDescriptorPayload668     AbckitCoreFunction *GetFunctionPayload()
669     {
670         return std::get<AbckitCoreFunction *>(impl);
671     }
672     /*
673      * Implementation for AbckitImportExportDescriptorKind::FIELD.
674      */
GetFieldPayloadAbckitStaticImportDescriptorPayload675     AbckitCoreField *GetFieldPayload()
676     {
677         return std::get<AbckitCoreField *>(impl);
678     }
679 };
680 
681 struct AbckitCoreImportDescriptorPayload {
682     std::variant<AbckitDynamicImportDescriptorPayload, AbckitStaticImportDescriptorPayload> impl;
683     /*
684      * Implementation for AbckitImportExportDescriptorKind::UNTYPED.
685      */
GetDynIdAbckitCoreImportDescriptorPayload686     AbckitDynamicImportDescriptorPayload &GetDynId()
687     {
688         return std::get<AbckitDynamicImportDescriptorPayload>(impl);
689     }
690     /*
691      * Implementation for static kinds.
692      */
GetStatIdAbckitCoreImportDescriptorPayload693     AbckitStaticImportDescriptorPayload GetStatId()
694     {
695         return std::get<AbckitStaticImportDescriptorPayload>(impl);
696     }
697 };
698 
699 struct AbckitArktsImportDescriptor {
700     /*
701      * Kind of the imported entity.
702      * Use AbckitImportExportDescriptorKind::UNTYPED for imports from dynamic modules.
703      * Other kinds are used for imports from static modules.
704      */
705     AbckitImportExportDescriptorKind kind = UNTYPED;
706     /*
707      * Data needed to work with the import.
708      */
709     AbckitCoreImportDescriptorPayload payload;
710     AbckitCoreImportDescriptor *core = nullptr;
711 };
712 
713 struct AbckitJsImportDescriptor {
714     /*
715      * Kind of the imported entity.
716      * Use AbckitImportExportDescriptorKind::UNTYPED for imports from dynamic modules.
717      * Other kinds are used for imports from static modules.
718      */
719     AbckitImportExportDescriptorKind kind = UNTYPED;
720     /*
721      * Data needed to work with the import.
722      */
723     AbckitCoreImportDescriptorPayload payload;
724     AbckitCoreImportDescriptor *core = nullptr;
725 };
726 
727 struct AbckitCoreImportDescriptor {
728     /*
729      * Back link to the importing module.
730      */
731     AbckitCoreModule *importingModule = nullptr;
732     /*
733      * Link to the module from which entity is imported.
734      */
735     AbckitCoreModule *importedModule = nullptr;
736 
737     std::variant<std::unique_ptr<AbckitJsImportDescriptor>, std::unique_ptr<AbckitArktsImportDescriptor>> impl;
GetArkTSImplAbckitCoreImportDescriptor738     AbckitArktsImportDescriptor *GetArkTSImpl()
739     {
740         return std::get<std::unique_ptr<AbckitArktsImportDescriptor>>(impl).get();
741     }
GetJsImplAbckitCoreImportDescriptor742     AbckitJsImportDescriptor *GetJsImpl()
743     {
744         return std::get<std::unique_ptr<AbckitJsImportDescriptor>>(impl).get();
745     }
746 };
747 
748 struct AbckitDynamicExportDescriptorPayload {
749     /*
750      * The kind of export. Used to determine where to look by the index.
751      */
752     AbckitDynamicExportKind kind = ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT;
753     /*
754      * For special StarExport case 'export * as <StarExport> from "..."'.
755      * It converts to NamespaceImport + LocalExport:
756      * import * as =ens{$i} from "...";
757      * export =ens{$i} as <StarExport>;
758      */
759     bool hasServiceImport = false;
760     /*
761      * For special StarExport case 'export * as <StarExport> from "..."'.
762      */
763     size_t serviceNamespaceImportIdx = 0;
764     /*
765      * Offset in the corresponding `XXX_exports` (depends on the `kind`) in mainline.
766      */
767     uint32_t moduleRecordIndexOff = 0;
768 };
769 
770 struct AbckitCoreExportDescriptorPayload {
771     std::variant<AbckitDynamicExportDescriptorPayload, AbckitCoreAnnotationInterface *, AbckitCoreClass *,
772                  AbckitCoreFunction *, AbckitCoreField *>
773         impl;
774 
775     /*
776      * Implementation for AbckitImportExportDescriptorKind::UNTYPED.
777      */
GetDynamicPayloadAbckitCoreExportDescriptorPayload778     AbckitDynamicExportDescriptorPayload &GetDynamicPayload()
779     {
780         return std::get<AbckitDynamicExportDescriptorPayload>(impl);
781     }
782     /*
783      * Payload for AbckitImportExportDescriptorKind::ANNOTATION.
784      * Should point to the LOCAL entity.
785      */
GetAnnotationInterfacePayloadAbckitCoreExportDescriptorPayload786     AbckitCoreAnnotationInterface *GetAnnotationInterfacePayload()
787     {
788         return std::get<AbckitCoreAnnotationInterface *>(impl);
789     }
790     /*
791      * Payload for AbckitImportExportDescriptorKind::CLASS.
792      * Should point to the LOCAL entity.
793      */
GetClassPayloadAbckitCoreExportDescriptorPayload794     AbckitCoreClass *GetClassPayload()
795     {
796         return std::get<AbckitCoreClass *>(impl);
797     }
798     /*
799      * Payload for AbckitImportExportDescriptorKind::FUNCTION.
800      * Should point to the LOCAL entity.
801      */
GetFunctionPayloadAbckitCoreExportDescriptorPayload802     AbckitCoreFunction *GetFunctionPayload()
803     {
804         return std::get<AbckitCoreFunction *>(impl);
805     }
806     /*
807      * Payload for AbckitImportExportDescriptorKind::FIELD.
808      * Should point to the LOCAL entity.
809      */
GetFieldPayloadAbckitCoreExportDescriptorPayload810     AbckitCoreField *GetFieldPayload()
811     {
812         return std::get<AbckitCoreField *>(impl);
813     }
814 };
815 
816 struct AbckitArktsExportDescriptor {
817     AbckitCoreExportDescriptor *core = nullptr;
818     /*
819      * Kind of the exported entity.
820      * Use AbckitImportExportDescriptorKind::UNTYPED for exports from dynamic modules.
821      * Other kinds are used for exports from static modules.
822      * NOTE: Use same enum as import API here. May need to rename this enum
823      * when implementing v2 API to something neutral, like AbckitDescriptorKind.
824      */
825     AbckitImportExportDescriptorKind kind = UNTYPED;
826     /*
827      * Data needed to work with the import.
828      */
829     AbckitCoreExportDescriptorPayload payload;
830 };
831 
832 struct AbckitJsExportDescriptor {
833     AbckitCoreExportDescriptor *core = nullptr;
834     /*
835      * Kind of the exported entity.
836      * Use AbckitImportExportDescriptorKind::UNTYPED for exports from dynamic modules.
837      * Other kinds are used for exports from static modules.
838      * NOTE: Use same enum as import API here. May need to rename this enum
839      * when implementing v2 API to something neutral, like AbckitDescriptorKind.
840      */
841     AbckitImportExportDescriptorKind kind = UNTYPED;
842     /*
843      * Data needed to work with the import.
844      */
845     AbckitCoreExportDescriptorPayload payload;
846 };
847 
848 struct AbckitCoreExportDescriptor {
849     /*
850      * Back link to the exporting module.
851      */
852     AbckitCoreModule *exportingModule = nullptr;
853     /*
854      * Link to the exported module.
855      */
856     AbckitCoreModule *exportedModule = nullptr;
857 
858     std::variant<std::unique_ptr<AbckitJsExportDescriptor>, std::unique_ptr<AbckitArktsExportDescriptor>> impl;
GetArkTSImplAbckitCoreExportDescriptor859     AbckitArktsExportDescriptor *GetArkTSImpl()
860     {
861         return std::get<std::unique_ptr<AbckitArktsExportDescriptor>>(impl).get();
862     }
GetJsImplAbckitCoreExportDescriptor863     AbckitJsExportDescriptor *GetJsImpl()
864     {
865         return std::get<std::unique_ptr<AbckitJsExportDescriptor>>(impl).get();
866     }
867 };
868 // NOLINTEND(misc-non-private-member-variables-in-classes)
869 
870 #endif  // LIBABCKIT_STD_METADATA_INSPECT_IMPL_H
871