1b1994897Sopenharmony_ci/**
2b1994897Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3b1994897Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4b1994897Sopenharmony_ci * you may not use this file except in compliance with the License.
5b1994897Sopenharmony_ci * You may obtain a copy of the License at
6b1994897Sopenharmony_ci *
7b1994897Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8b1994897Sopenharmony_ci *
9b1994897Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10b1994897Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11b1994897Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12b1994897Sopenharmony_ci * See the License for the specific language governing permissions and
13b1994897Sopenharmony_ci * limitations under the License.
14b1994897Sopenharmony_ci */
15b1994897Sopenharmony_ci
16b1994897Sopenharmony_ci#ifndef LIBPANDAFILE_FILE_ITEMS_H
17b1994897Sopenharmony_ci#define LIBPANDAFILE_FILE_ITEMS_H
18b1994897Sopenharmony_ci
19b1994897Sopenharmony_ci#include "file.h"
20b1994897Sopenharmony_ci#include "file_writer.h"
21b1994897Sopenharmony_ci#include "macros.h"
22b1994897Sopenharmony_ci#include "modifiers.h"
23b1994897Sopenharmony_ci#include "type.h"
24b1994897Sopenharmony_ci#include "file_format_version.h"
25b1994897Sopenharmony_ci#include "source_lang_enum.h"
26b1994897Sopenharmony_ci
27b1994897Sopenharmony_ci#include <cstddef>
28b1994897Sopenharmony_ci#include <cstdint>
29b1994897Sopenharmony_ci
30b1994897Sopenharmony_ci#include <algorithm>
31b1994897Sopenharmony_ci#include <memory>
32b1994897Sopenharmony_ci#include <string>
33b1994897Sopenharmony_ci#include <variant>
34b1994897Sopenharmony_ci#include <vector>
35b1994897Sopenharmony_ci#include <list>
36b1994897Sopenharmony_ci#include <set>
37b1994897Sopenharmony_ci
38b1994897Sopenharmony_cinamespace panda::panda_file {
39b1994897Sopenharmony_ci
40b1994897Sopenharmony_cienum class ClassTag : uint8_t {
41b1994897Sopenharmony_ci    NOTHING = 0x00,
42b1994897Sopenharmony_ci    INTERFACES = 0x01,
43b1994897Sopenharmony_ci    SOURCE_LANG = 0x02,
44b1994897Sopenharmony_ci    RUNTIME_ANNOTATION = 0x03,
45b1994897Sopenharmony_ci    ANNOTATION = 0x04,
46b1994897Sopenharmony_ci    RUNTIME_TYPE_ANNOTATION = 0x05,
47b1994897Sopenharmony_ci    TYPE_ANNOTATION = 0x06,
48b1994897Sopenharmony_ci    SOURCE_FILE = 0x07
49b1994897Sopenharmony_ci};
50b1994897Sopenharmony_ci
51b1994897Sopenharmony_cienum class MethodTag : uint8_t {
52b1994897Sopenharmony_ci    NOTHING = 0x00,
53b1994897Sopenharmony_ci    CODE = 0x01,
54b1994897Sopenharmony_ci    SOURCE_LANG = 0x02,
55b1994897Sopenharmony_ci    RUNTIME_ANNOTATION = 0x03,
56b1994897Sopenharmony_ci    RUNTIME_PARAM_ANNOTATION = 0x04,
57b1994897Sopenharmony_ci    DEBUG_INFO = 0x05,
58b1994897Sopenharmony_ci    ANNOTATION = 0x06,
59b1994897Sopenharmony_ci    PARAM_ANNOTATION = 0x07,
60b1994897Sopenharmony_ci    TYPE_ANNOTATION = 0x08,
61b1994897Sopenharmony_ci    RUNTIME_TYPE_ANNOTATION = 0x09
62b1994897Sopenharmony_ci};
63b1994897Sopenharmony_ci
64b1994897Sopenharmony_cienum class FieldTag : uint8_t {
65b1994897Sopenharmony_ci    NOTHING = 0x00,
66b1994897Sopenharmony_ci    INT_VALUE = 0x01,
67b1994897Sopenharmony_ci    VALUE = 0x02,
68b1994897Sopenharmony_ci    RUNTIME_ANNOTATION = 0x03,
69b1994897Sopenharmony_ci    ANNOTATION = 0x04,
70b1994897Sopenharmony_ci    RUNTIME_TYPE_ANNOTATION = 0x05,
71b1994897Sopenharmony_ci    TYPE_ANNOTATION = 0x06
72b1994897Sopenharmony_ci};
73b1994897Sopenharmony_ci
74b1994897Sopenharmony_cienum class FunctionKind : uint8_t {
75b1994897Sopenharmony_ci    NONE = 0x0,
76b1994897Sopenharmony_ci    FUNCTION = 0x1,
77b1994897Sopenharmony_ci    NC_FUNCTION = 0x2,
78b1994897Sopenharmony_ci    GENERATOR_FUNCTION = 0x3,
79b1994897Sopenharmony_ci    ASYNC_FUNCTION = 0x4,
80b1994897Sopenharmony_ci    ASYNC_GENERATOR_FUNCTION = 0x5,
81b1994897Sopenharmony_ci    ASYNC_NC_FUNCTION = 0x6,
82b1994897Sopenharmony_ci    CONCURRENT_FUNCTION = 0x7,
83b1994897Sopenharmony_ci    // Use bit operation to support both sendable function and async sendable function
84b1994897Sopenharmony_ci    SENDABLE_FUNCTION = 1 << 3
85b1994897Sopenharmony_ci};
86b1994897Sopenharmony_ci
87b1994897Sopenharmony_cienum class ItemRank : uint8_t {
88b1994897Sopenharmony_ci    DEFAULT_RANK = 0x0,
89b1994897Sopenharmony_ci    STRING_ITEM_RANK = 0x1,
90b1994897Sopenharmony_ci    CLASS_ITEM_RANK = 0x2
91b1994897Sopenharmony_ci};
92b1994897Sopenharmony_ci
93b1994897Sopenharmony_cienum class ItemTypes {
94b1994897Sopenharmony_ci    ANNOTATION_ITEM,
95b1994897Sopenharmony_ci    CATCH_BLOCK_ITEM,
96b1994897Sopenharmony_ci    CLASS_INDEX_ITEM,
97b1994897Sopenharmony_ci    CLASS_ITEM,
98b1994897Sopenharmony_ci    CODE_ITEM,
99b1994897Sopenharmony_ci    DEBUG_INFO_ITEM,
100b1994897Sopenharmony_ci    END_ITEM,
101b1994897Sopenharmony_ci    FIELD_INDEX_ITEM,
102b1994897Sopenharmony_ci    FIELD_ITEM,
103b1994897Sopenharmony_ci    FOREIGN_CLASS_ITEM,
104b1994897Sopenharmony_ci    FOREIGN_FIELD_ITEM,
105b1994897Sopenharmony_ci    FOREIGN_METHOD_ITEM,
106b1994897Sopenharmony_ci    INDEX_HEADER,
107b1994897Sopenharmony_ci    INDEX_SECTION,
108b1994897Sopenharmony_ci    LINE_NUMBER_PROGRAM_INDEX_ITEM,
109b1994897Sopenharmony_ci    LINE_NUMBER_PROGRAM_ITEM,
110b1994897Sopenharmony_ci    LITERAL_ARRAY_ITEM,
111b1994897Sopenharmony_ci    LITERAL_ITEM,
112b1994897Sopenharmony_ci    METHOD_HANDLE_ITEM,
113b1994897Sopenharmony_ci    METHOD_INDEX_ITEM,
114b1994897Sopenharmony_ci    METHOD_ITEM,
115b1994897Sopenharmony_ci    PARAM_ANNOTATIONS_ITEM,
116b1994897Sopenharmony_ci    PRIMITIVE_TYPE_ITEM,
117b1994897Sopenharmony_ci    PROTO_INDEX_ITEM,
118b1994897Sopenharmony_ci    PROTO_ITEM,
119b1994897Sopenharmony_ci    STRING_ITEM,
120b1994897Sopenharmony_ci    TRY_BLOCK_ITEM,
121b1994897Sopenharmony_ci    VALUE_ITEM
122b1994897Sopenharmony_ci};
123b1994897Sopenharmony_ci
124b1994897Sopenharmony_cibool IsDynamicLanguage(panda::panda_file::SourceLang lang);
125b1994897Sopenharmony_cistd::optional<panda::panda_file::SourceLang> LanguageFromString(const std::string_view &lang);
126b1994897Sopenharmony_ciconst char *LanguageToString(panda::panda_file::SourceLang lang);
127b1994897Sopenharmony_ciconst char *GetCtorName(panda::panda_file::SourceLang lang);
128b1994897Sopenharmony_ciconst char *GetCctorName(panda::panda_file::SourceLang lang);
129b1994897Sopenharmony_ciconst char *GetStringClassDescriptor(panda::panda_file::SourceLang lang);
130b1994897Sopenharmony_cistd::string ItemTypeToString(ItemTypes type);
131b1994897Sopenharmony_ci
132b1994897Sopenharmony_cistatic constexpr size_t ID_SIZE = File::EntityId::GetSize();
133b1994897Sopenharmony_cistatic constexpr size_t IDX_SIZE = sizeof(uint16_t);
134b1994897Sopenharmony_cistatic constexpr size_t TAG_SIZE = 1;
135b1994897Sopenharmony_cistatic constexpr uint32_t INVALID_OFFSET = std::numeric_limits<uint32_t>::max();
136b1994897Sopenharmony_cistatic constexpr uint32_t INVALID_INDEX = std::numeric_limits<uint32_t>::max();
137b1994897Sopenharmony_cistatic constexpr uint32_t MAX_INDEX_32 = std::numeric_limits<uint32_t>::max();
138b1994897Sopenharmony_cistatic constexpr uint32_t FLAG_WIDTH = 8;
139b1994897Sopenharmony_cistatic constexpr uint32_t FUNTION_KIND_WIDTH = 8;
140b1994897Sopenharmony_cistatic constexpr uint32_t FUNCTION_KIND_MASK = 0xFF00;
141b1994897Sopenharmony_cistatic constexpr uint32_t FLAG_MASK = 0xFF;
142b1994897Sopenharmony_ci
143b1994897Sopenharmony_ciconstexpr uint16_t INVALID_INDEX_16 = std::numeric_limits<uint16_t>::max();
144b1994897Sopenharmony_ciconstexpr uint32_t MAX_INDEX_16 = std::numeric_limits<uint16_t>::max() - 1;
145b1994897Sopenharmony_ci
146b1994897Sopenharmony_ciconstexpr uint32_t PGO_STRING_DEFAULT_COUNT = 5;
147b1994897Sopenharmony_ciconstexpr uint32_t PGO_CLASS_DEFAULT_COUNT = 3;
148b1994897Sopenharmony_ciconstexpr uint32_t PGO_CODE_DEFAULT_COUNT = 1;
149b1994897Sopenharmony_ci
150b1994897Sopenharmony_ciconstexpr std::string_view STRING_ITEM = "string_item";
151b1994897Sopenharmony_ciconstexpr std::string_view CLASS_ITEM = "class_item";
152b1994897Sopenharmony_ciconstexpr std::string_view CODE_ITEM = "code_item";
153b1994897Sopenharmony_ci
154b1994897Sopenharmony_cienum class IndexType {
155b1994897Sopenharmony_ci    // 16-bit indexes
156b1994897Sopenharmony_ci    CLASS = 0x0,
157b1994897Sopenharmony_ci    METHOD_STRING_LITERAL = 0x1,
158b1994897Sopenharmony_ci    FIELD = 0x2,
159b1994897Sopenharmony_ci    PROTO = 0x3,
160b1994897Sopenharmony_ci    LAST_16 = PROTO,
161b1994897Sopenharmony_ci    // 32-bit indexes
162b1994897Sopenharmony_ci    LINE_NUMBER_PROG = 0x04,
163b1994897Sopenharmony_ci    LAST_32 = LINE_NUMBER_PROG,
164b1994897Sopenharmony_ci
165b1994897Sopenharmony_ci    NONE
166b1994897Sopenharmony_ci};
167b1994897Sopenharmony_ci
168b1994897Sopenharmony_cistatic constexpr size_t INDEX_COUNT_16 = static_cast<size_t>(IndexType::LAST_16) + 1;
169b1994897Sopenharmony_ci
170b1994897Sopenharmony_ciclass IndexedItem;
171b1994897Sopenharmony_ciclass ItemContainer;
172b1994897Sopenharmony_ci
173b1994897Sopenharmony_ciclass BaseItem {
174b1994897Sopenharmony_cipublic:
175b1994897Sopenharmony_ci    using VisitorCallBack = std::function<bool(BaseItem *)>;
176b1994897Sopenharmony_ci
177b1994897Sopenharmony_ci    BaseItem() = default;
178b1994897Sopenharmony_ci    virtual ~BaseItem() = default;
179b1994897Sopenharmony_ci
180b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(BaseItem);
181b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(BaseItem);
182b1994897Sopenharmony_ci
183b1994897Sopenharmony_ci    size_t GetSize() const
184b1994897Sopenharmony_ci    {
185b1994897Sopenharmony_ci        return CalculateSize();
186b1994897Sopenharmony_ci    }
187b1994897Sopenharmony_ci
188b1994897Sopenharmony_ci    virtual size_t CalculateSize() const = 0;
189b1994897Sopenharmony_ci
190b1994897Sopenharmony_ci    virtual void ComputeLayout() {}
191b1994897Sopenharmony_ci
192b1994897Sopenharmony_ci    virtual size_t Alignment()
193b1994897Sopenharmony_ci    {
194b1994897Sopenharmony_ci        return 1;
195b1994897Sopenharmony_ci    }
196b1994897Sopenharmony_ci
197b1994897Sopenharmony_ci    virtual bool IsForeign() const
198b1994897Sopenharmony_ci    {
199b1994897Sopenharmony_ci        return false;
200b1994897Sopenharmony_ci    }
201b1994897Sopenharmony_ci
202b1994897Sopenharmony_ci    uint32_t GetOffset() const
203b1994897Sopenharmony_ci    {
204b1994897Sopenharmony_ci        return offset_;
205b1994897Sopenharmony_ci    }
206b1994897Sopenharmony_ci
207b1994897Sopenharmony_ci    panda_file::File::EntityId GetFileId() const
208b1994897Sopenharmony_ci    {
209b1994897Sopenharmony_ci        return panda_file::File::EntityId(offset_);
210b1994897Sopenharmony_ci    }
211b1994897Sopenharmony_ci
212b1994897Sopenharmony_ci    void SetOffset(uint32_t offset)
213b1994897Sopenharmony_ci    {
214b1994897Sopenharmony_ci        offset_ = offset;
215b1994897Sopenharmony_ci    }
216b1994897Sopenharmony_ci
217b1994897Sopenharmony_ci    bool NeedsEmit() const
218b1994897Sopenharmony_ci    {
219b1994897Sopenharmony_ci        return needs_emit_;
220b1994897Sopenharmony_ci    }
221b1994897Sopenharmony_ci
222b1994897Sopenharmony_ci    void SetNeedsEmit(bool needs_emit)
223b1994897Sopenharmony_ci    {
224b1994897Sopenharmony_ci        needs_emit_ = needs_emit;
225b1994897Sopenharmony_ci    }
226b1994897Sopenharmony_ci
227b1994897Sopenharmony_ci    const std::list<IndexedItem *> &GetIndexDependencies() const
228b1994897Sopenharmony_ci    {
229b1994897Sopenharmony_ci        return index_deps_;
230b1994897Sopenharmony_ci    }
231b1994897Sopenharmony_ci
232b1994897Sopenharmony_ci    void AddIndexDependency(IndexedItem *item)
233b1994897Sopenharmony_ci    {
234b1994897Sopenharmony_ci        ASSERT(item != nullptr);
235b1994897Sopenharmony_ci        index_deps_.push_back(item);
236b1994897Sopenharmony_ci    }
237b1994897Sopenharmony_ci
238b1994897Sopenharmony_ci    void SetOrderIndex(uint32_t order)
239b1994897Sopenharmony_ci    {
240b1994897Sopenharmony_ci        order_ = order;
241b1994897Sopenharmony_ci    }
242b1994897Sopenharmony_ci
243b1994897Sopenharmony_ci    uint32_t GetOrderIndex() const
244b1994897Sopenharmony_ci    {
245b1994897Sopenharmony_ci        return order_;
246b1994897Sopenharmony_ci    }
247b1994897Sopenharmony_ci
248b1994897Sopenharmony_ci    bool HasOrderIndex() const
249b1994897Sopenharmony_ci    {
250b1994897Sopenharmony_ci        return order_ != INVALID_INDEX;
251b1994897Sopenharmony_ci    }
252b1994897Sopenharmony_ci
253b1994897Sopenharmony_ci    virtual bool Write(Writer *writer) = 0;
254b1994897Sopenharmony_ci
255b1994897Sopenharmony_ci    std::string GetName() const;
256b1994897Sopenharmony_ci
257b1994897Sopenharmony_ci    virtual ItemTypes GetItemType() const = 0;
258b1994897Sopenharmony_ci
259b1994897Sopenharmony_ci    virtual void Dump([[maybe_unused]] std::ostream &os) const {}
260b1994897Sopenharmony_ci
261b1994897Sopenharmony_ci    virtual void Visit([[maybe_unused]] const VisitorCallBack &cb) {}
262b1994897Sopenharmony_ci
263b1994897Sopenharmony_ci    void SetPGORank(uint32_t rank)
264b1994897Sopenharmony_ci    {
265b1994897Sopenharmony_ci        pgo_rank_ = rank;
266b1994897Sopenharmony_ci    }
267b1994897Sopenharmony_ci
268b1994897Sopenharmony_ci    uint32_t GetPGORank() const
269b1994897Sopenharmony_ci    {
270b1994897Sopenharmony_ci        return pgo_rank_;
271b1994897Sopenharmony_ci    }
272b1994897Sopenharmony_ci
273b1994897Sopenharmony_ci    void SetOriginalRank(uint32_t rank)
274b1994897Sopenharmony_ci    {
275b1994897Sopenharmony_ci        original_rank_ = rank;
276b1994897Sopenharmony_ci    }
277b1994897Sopenharmony_ci
278b1994897Sopenharmony_ci    uint32_t GetOriginalRank() const
279b1994897Sopenharmony_ci    {
280b1994897Sopenharmony_ci        return original_rank_;
281b1994897Sopenharmony_ci    }
282b1994897Sopenharmony_ci
283b1994897Sopenharmony_ci    void SetReLayoutRank(ItemRank rank)
284b1994897Sopenharmony_ci    {
285b1994897Sopenharmony_ci        re_layout_rank_ = rank;
286b1994897Sopenharmony_ci    }
287b1994897Sopenharmony_ci
288b1994897Sopenharmony_ci    ItemRank GetReLayoutRank() const
289b1994897Sopenharmony_ci    {
290b1994897Sopenharmony_ci        return re_layout_rank_;
291b1994897Sopenharmony_ci    }
292b1994897Sopenharmony_ci
293b1994897Sopenharmony_ciprivate:
294b1994897Sopenharmony_ci    bool needs_emit_ {true};
295b1994897Sopenharmony_ci    uint32_t offset_ {0};
296b1994897Sopenharmony_ci    uint32_t order_ {INVALID_INDEX};
297b1994897Sopenharmony_ci    std::list<IndexedItem *> index_deps_;
298b1994897Sopenharmony_ci    uint32_t pgo_rank_ {0};
299b1994897Sopenharmony_ci    uint32_t original_rank_ {0};
300b1994897Sopenharmony_ci    ItemRank re_layout_rank_ {ItemRank::DEFAULT_RANK};
301b1994897Sopenharmony_ci};
302b1994897Sopenharmony_ci
303b1994897Sopenharmony_ciclass IndexedItem : public BaseItem {
304b1994897Sopenharmony_cipublic:
305b1994897Sopenharmony_ci    explicit IndexedItem(ItemContainer *container);
306b1994897Sopenharmony_ci
307b1994897Sopenharmony_ci    uint32_t GetIndex(const BaseItem *item) const
308b1994897Sopenharmony_ci    {
309b1994897Sopenharmony_ci        auto *idx = FindIndex(item);
310b1994897Sopenharmony_ci        ASSERT(idx != nullptr);
311b1994897Sopenharmony_ci        return idx->index;
312b1994897Sopenharmony_ci    }
313b1994897Sopenharmony_ci
314b1994897Sopenharmony_ci    bool HasIndex(const BaseItem *item) const
315b1994897Sopenharmony_ci    {
316b1994897Sopenharmony_ci        return FindIndex(item) != nullptr;
317b1994897Sopenharmony_ci    }
318b1994897Sopenharmony_ci
319b1994897Sopenharmony_ci    void SetIndex(const BaseItem *start, const BaseItem *end, uint32_t index)
320b1994897Sopenharmony_ci    {
321b1994897Sopenharmony_ci        ASSERT(FindIndex(start, end) == nullptr);
322b1994897Sopenharmony_ci        indexes_.push_back({start, end, index});
323b1994897Sopenharmony_ci    }
324b1994897Sopenharmony_ci
325b1994897Sopenharmony_ci    void ClearIndexes()
326b1994897Sopenharmony_ci    {
327b1994897Sopenharmony_ci        indexes_.clear();
328b1994897Sopenharmony_ci    }
329b1994897Sopenharmony_ci
330b1994897Sopenharmony_ci    void IncRefCount()
331b1994897Sopenharmony_ci    {
332b1994897Sopenharmony_ci        ++ref_count_;
333b1994897Sopenharmony_ci    }
334b1994897Sopenharmony_ci
335b1994897Sopenharmony_ci    void DecRefCount()
336b1994897Sopenharmony_ci    {
337b1994897Sopenharmony_ci        ASSERT(ref_count_ != 0);
338b1994897Sopenharmony_ci        --ref_count_;
339b1994897Sopenharmony_ci    }
340b1994897Sopenharmony_ci
341b1994897Sopenharmony_ci    size_t GetRefCount() const
342b1994897Sopenharmony_ci    {
343b1994897Sopenharmony_ci        return ref_count_;
344b1994897Sopenharmony_ci    }
345b1994897Sopenharmony_ci
346b1994897Sopenharmony_ci    virtual IndexType GetIndexType() const
347b1994897Sopenharmony_ci    {
348b1994897Sopenharmony_ci        return IndexType::NONE;
349b1994897Sopenharmony_ci    }
350b1994897Sopenharmony_ci
351b1994897Sopenharmony_ci    size_t GetIndexedItemCount() const
352b1994897Sopenharmony_ci    {
353b1994897Sopenharmony_ci        return item_global_index_;
354b1994897Sopenharmony_ci    }
355b1994897Sopenharmony_ci
356b1994897Sopenharmony_ciprivate:
357b1994897Sopenharmony_ci    struct Index {
358b1994897Sopenharmony_ci        const BaseItem *start;
359b1994897Sopenharmony_ci        const BaseItem *end;
360b1994897Sopenharmony_ci        uint32_t index;
361b1994897Sopenharmony_ci    };
362b1994897Sopenharmony_ci
363b1994897Sopenharmony_ci    const Index *FindIndex(const BaseItem *start, const BaseItem *end) const
364b1994897Sopenharmony_ci    {
365b1994897Sopenharmony_ci        auto it = std::find_if(indexes_.cbegin(), indexes_.cend(),
366b1994897Sopenharmony_ci                               [start, end](const Index &idx) { return idx.start == start && idx.end == end; });
367b1994897Sopenharmony_ci
368b1994897Sopenharmony_ci        return it != indexes_.cend() ? &*it : nullptr;
369b1994897Sopenharmony_ci    }
370b1994897Sopenharmony_ci
371b1994897Sopenharmony_ci    const Index *FindIndex(const BaseItem *item) const
372b1994897Sopenharmony_ci    {
373b1994897Sopenharmony_ci        ASSERT(item->HasOrderIndex());
374b1994897Sopenharmony_ci        auto order_idx = item->GetOrderIndex();
375b1994897Sopenharmony_ci
376b1994897Sopenharmony_ci        auto it = std::find_if(indexes_.cbegin(), indexes_.cend(), [order_idx](const Index &idx) {
377b1994897Sopenharmony_ci            if (idx.start == nullptr && idx.end == nullptr) {
378b1994897Sopenharmony_ci                return true;
379b1994897Sopenharmony_ci            }
380b1994897Sopenharmony_ci
381b1994897Sopenharmony_ci            if (idx.start == nullptr || idx.end == nullptr) {
382b1994897Sopenharmony_ci                return false;
383b1994897Sopenharmony_ci            }
384b1994897Sopenharmony_ci
385b1994897Sopenharmony_ci            ASSERT(idx.start->HasOrderIndex());
386b1994897Sopenharmony_ci            ASSERT(idx.end->HasOrderIndex());
387b1994897Sopenharmony_ci            return idx.start->GetOrderIndex() <= order_idx && order_idx < idx.end->GetOrderIndex();
388b1994897Sopenharmony_ci        });
389b1994897Sopenharmony_ci
390b1994897Sopenharmony_ci        return it != indexes_.cend() ? &*it : nullptr;
391b1994897Sopenharmony_ci    }
392b1994897Sopenharmony_ci
393b1994897Sopenharmony_ci    std::vector<Index> indexes_;
394b1994897Sopenharmony_ci    size_t ref_count_ {1};
395b1994897Sopenharmony_ci    size_t item_global_index_ {0};
396b1994897Sopenharmony_ci};
397b1994897Sopenharmony_ci
398b1994897Sopenharmony_ciclass TypeItem : public IndexedItem {
399b1994897Sopenharmony_cipublic:
400b1994897Sopenharmony_ci    explicit TypeItem(Type type, ItemContainer *container) : IndexedItem(container), type_(type) {}
401b1994897Sopenharmony_ci
402b1994897Sopenharmony_ci    explicit TypeItem(Type::TypeId type_id, ItemContainer *container) : IndexedItem(container), type_(type_id) {}
403b1994897Sopenharmony_ci
404b1994897Sopenharmony_ci    ~TypeItem() override = default;
405b1994897Sopenharmony_ci
406b1994897Sopenharmony_ci    Type GetType() const
407b1994897Sopenharmony_ci    {
408b1994897Sopenharmony_ci        return type_;
409b1994897Sopenharmony_ci    }
410b1994897Sopenharmony_ci
411b1994897Sopenharmony_ci    IndexType GetIndexType() const override
412b1994897Sopenharmony_ci    {
413b1994897Sopenharmony_ci        return IndexType::CLASS;
414b1994897Sopenharmony_ci    }
415b1994897Sopenharmony_ci
416b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(TypeItem);
417b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(TypeItem);
418b1994897Sopenharmony_ci
419b1994897Sopenharmony_ciprivate:
420b1994897Sopenharmony_ci    Type type_;
421b1994897Sopenharmony_ci};
422b1994897Sopenharmony_ci
423b1994897Sopenharmony_ciclass PrimitiveTypeItem : public TypeItem {
424b1994897Sopenharmony_cipublic:
425b1994897Sopenharmony_ci    explicit PrimitiveTypeItem(Type type, ItemContainer *container) : PrimitiveTypeItem(type.GetId(), container) {}
426b1994897Sopenharmony_ci
427b1994897Sopenharmony_ci    explicit PrimitiveTypeItem(Type::TypeId type_id, ItemContainer *container) : TypeItem(type_id, container)
428b1994897Sopenharmony_ci    {
429b1994897Sopenharmony_ci        ASSERT(GetType().IsPrimitive());
430b1994897Sopenharmony_ci        SetNeedsEmit(false);
431b1994897Sopenharmony_ci        SetOffset(GetType().GetFieldEncoding());
432b1994897Sopenharmony_ci    }
433b1994897Sopenharmony_ci
434b1994897Sopenharmony_ci    ~PrimitiveTypeItem() override = default;
435b1994897Sopenharmony_ci
436b1994897Sopenharmony_ci    size_t CalculateSize() const override
437b1994897Sopenharmony_ci    {
438b1994897Sopenharmony_ci        return 0;
439b1994897Sopenharmony_ci    }
440b1994897Sopenharmony_ci
441b1994897Sopenharmony_ci    bool Write([[maybe_unused]] Writer *writer) override
442b1994897Sopenharmony_ci    {
443b1994897Sopenharmony_ci        return true;
444b1994897Sopenharmony_ci    }
445b1994897Sopenharmony_ci
446b1994897Sopenharmony_ci    ItemTypes GetItemType() const override
447b1994897Sopenharmony_ci    {
448b1994897Sopenharmony_ci        return ItemTypes::PRIMITIVE_TYPE_ITEM;
449b1994897Sopenharmony_ci    }
450b1994897Sopenharmony_ci
451b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(PrimitiveTypeItem);
452b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(PrimitiveTypeItem);
453b1994897Sopenharmony_ci};
454b1994897Sopenharmony_ci
455b1994897Sopenharmony_ciclass StringItem : public IndexedItem {
456b1994897Sopenharmony_cipublic:
457b1994897Sopenharmony_ci    explicit StringItem(std::string str, ItemContainer *container);
458b1994897Sopenharmony_ci
459b1994897Sopenharmony_ci    explicit StringItem(File::StringData data, ItemContainer *container);
460b1994897Sopenharmony_ci
461b1994897Sopenharmony_ci    ~StringItem() override = default;
462b1994897Sopenharmony_ci
463b1994897Sopenharmony_ci    size_t CalculateSize() const override;
464b1994897Sopenharmony_ci
465b1994897Sopenharmony_ci    bool Write(Writer *writer) override;
466b1994897Sopenharmony_ci
467b1994897Sopenharmony_ci    ItemTypes GetItemType() const override
468b1994897Sopenharmony_ci    {
469b1994897Sopenharmony_ci        return ItemTypes::STRING_ITEM;
470b1994897Sopenharmony_ci    }
471b1994897Sopenharmony_ci
472b1994897Sopenharmony_ci    const std::string &GetData() const
473b1994897Sopenharmony_ci    {
474b1994897Sopenharmony_ci        return str_;
475b1994897Sopenharmony_ci    }
476b1994897Sopenharmony_ci
477b1994897Sopenharmony_ci    size_t GetUtf16Len() const
478b1994897Sopenharmony_ci    {
479b1994897Sopenharmony_ci        return utf16_length_;
480b1994897Sopenharmony_ci    }
481b1994897Sopenharmony_ci
482b1994897Sopenharmony_ci    IndexType GetIndexType() const override
483b1994897Sopenharmony_ci    {
484b1994897Sopenharmony_ci        return IndexType::METHOD_STRING_LITERAL;
485b1994897Sopenharmony_ci    }
486b1994897Sopenharmony_ci
487b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(StringItem);
488b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(StringItem);
489b1994897Sopenharmony_ci
490b1994897Sopenharmony_ciprivate:
491b1994897Sopenharmony_ci    std::string str_;
492b1994897Sopenharmony_ci    size_t utf16_length_;
493b1994897Sopenharmony_ci    size_t is_ascii_ = 0;
494b1994897Sopenharmony_ci};
495b1994897Sopenharmony_ci
496b1994897Sopenharmony_ciclass AnnotationItem;
497b1994897Sopenharmony_ciclass BaseClassItem;
498b1994897Sopenharmony_ciclass ClassItem;
499b1994897Sopenharmony_ciclass ForeignClassItem;
500b1994897Sopenharmony_ciclass ValueItem;
501b1994897Sopenharmony_ci
502b1994897Sopenharmony_ciclass BaseFieldItem : public IndexedItem {
503b1994897Sopenharmony_cipublic:
504b1994897Sopenharmony_ci    IndexType GetIndexType() const override
505b1994897Sopenharmony_ci    {
506b1994897Sopenharmony_ci        return IndexType::FIELD;
507b1994897Sopenharmony_ci    }
508b1994897Sopenharmony_ci
509b1994897Sopenharmony_ci    StringItem *GetNameItem() const
510b1994897Sopenharmony_ci    {
511b1994897Sopenharmony_ci        return name_;
512b1994897Sopenharmony_ci    }
513b1994897Sopenharmony_ci
514b1994897Sopenharmony_ci    ~BaseFieldItem() override = default;
515b1994897Sopenharmony_ci
516b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(BaseFieldItem);
517b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(BaseFieldItem);
518b1994897Sopenharmony_ci
519b1994897Sopenharmony_ciprotected:
520b1994897Sopenharmony_ci    BaseFieldItem(BaseClassItem *cls, StringItem *name, TypeItem *type, ItemContainer *container);
521b1994897Sopenharmony_ci
522b1994897Sopenharmony_ci    size_t CalculateSize() const override;
523b1994897Sopenharmony_ci
524b1994897Sopenharmony_ci    bool Write(Writer *writer) override;
525b1994897Sopenharmony_ci
526b1994897Sopenharmony_ciprivate:
527b1994897Sopenharmony_ci    BaseClassItem *class_;
528b1994897Sopenharmony_ci    StringItem *name_;
529b1994897Sopenharmony_ci    TypeItem *type_;
530b1994897Sopenharmony_ci};
531b1994897Sopenharmony_ci
532b1994897Sopenharmony_ciclass FieldItem : public BaseFieldItem {
533b1994897Sopenharmony_cipublic:
534b1994897Sopenharmony_ci    FieldItem(ClassItem *cls, StringItem *name, TypeItem *type, uint32_t access_flags, ItemContainer *container);
535b1994897Sopenharmony_ci
536b1994897Sopenharmony_ci    ~FieldItem() override = default;
537b1994897Sopenharmony_ci
538b1994897Sopenharmony_ci    void SetValue(ValueItem *value);
539b1994897Sopenharmony_ci
540b1994897Sopenharmony_ci    ValueItem *GetValue() const
541b1994897Sopenharmony_ci    {
542b1994897Sopenharmony_ci        return value_;
543b1994897Sopenharmony_ci    }
544b1994897Sopenharmony_ci
545b1994897Sopenharmony_ci    void AddRuntimeAnnotation(AnnotationItem *runtime_annotation)
546b1994897Sopenharmony_ci    {
547b1994897Sopenharmony_ci        runtime_annotations_.push_back(runtime_annotation);
548b1994897Sopenharmony_ci    }
549b1994897Sopenharmony_ci
550b1994897Sopenharmony_ci    void AddAnnotation(AnnotationItem *annotation)
551b1994897Sopenharmony_ci    {
552b1994897Sopenharmony_ci        annotations_.push_back(annotation);
553b1994897Sopenharmony_ci    }
554b1994897Sopenharmony_ci
555b1994897Sopenharmony_ci    void AddRuntimeTypeAnnotation(AnnotationItem *runtime_type_annotation)
556b1994897Sopenharmony_ci    {
557b1994897Sopenharmony_ci        runtime_type_annotations_.push_back(runtime_type_annotation);
558b1994897Sopenharmony_ci    }
559b1994897Sopenharmony_ci
560b1994897Sopenharmony_ci    void AddTypeAnnotation(AnnotationItem *type_annotation)
561b1994897Sopenharmony_ci    {
562b1994897Sopenharmony_ci        type_annotations_.push_back(type_annotation);
563b1994897Sopenharmony_ci    }
564b1994897Sopenharmony_ci
565b1994897Sopenharmony_ci    size_t CalculateSize() const override;
566b1994897Sopenharmony_ci
567b1994897Sopenharmony_ci    bool Write(Writer *writer) override;
568b1994897Sopenharmony_ci
569b1994897Sopenharmony_ci    ItemTypes GetItemType() const override
570b1994897Sopenharmony_ci    {
571b1994897Sopenharmony_ci        return ItemTypes::FIELD_ITEM;
572b1994897Sopenharmony_ci    }
573b1994897Sopenharmony_ci
574b1994897Sopenharmony_ci    std::vector<AnnotationItem *> *GetRuntimeAnnotations()
575b1994897Sopenharmony_ci    {
576b1994897Sopenharmony_ci        return &runtime_annotations_;
577b1994897Sopenharmony_ci    }
578b1994897Sopenharmony_ci
579b1994897Sopenharmony_ci    std::vector<AnnotationItem *> *GetAnnotations()
580b1994897Sopenharmony_ci    {
581b1994897Sopenharmony_ci        return &annotations_;
582b1994897Sopenharmony_ci    }
583b1994897Sopenharmony_ci
584b1994897Sopenharmony_ci    std::vector<AnnotationItem *> *GetTypeAnnotations()
585b1994897Sopenharmony_ci    {
586b1994897Sopenharmony_ci        return &type_annotations_;
587b1994897Sopenharmony_ci    }
588b1994897Sopenharmony_ci
589b1994897Sopenharmony_ci    std::vector<AnnotationItem *> *GetRuntimeTypeAnnotations()
590b1994897Sopenharmony_ci    {
591b1994897Sopenharmony_ci        return &runtime_type_annotations_;
592b1994897Sopenharmony_ci    }
593b1994897Sopenharmony_ci
594b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(FieldItem);
595b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(FieldItem);
596b1994897Sopenharmony_ci
597b1994897Sopenharmony_ciprivate:
598b1994897Sopenharmony_ci    bool WriteValue(Writer *writer);
599b1994897Sopenharmony_ci
600b1994897Sopenharmony_ci    bool WriteAnnotations(Writer *writer);
601b1994897Sopenharmony_ci
602b1994897Sopenharmony_ci    bool WriteTaggedData(Writer *writer);
603b1994897Sopenharmony_ci
604b1994897Sopenharmony_ci    uint32_t access_flags_;
605b1994897Sopenharmony_ci    ValueItem *value_;
606b1994897Sopenharmony_ci    std::vector<AnnotationItem *> runtime_annotations_;
607b1994897Sopenharmony_ci    std::vector<AnnotationItem *> annotations_;
608b1994897Sopenharmony_ci    std::vector<AnnotationItem *> type_annotations_;
609b1994897Sopenharmony_ci    std::vector<AnnotationItem *> runtime_type_annotations_;
610b1994897Sopenharmony_ci};
611b1994897Sopenharmony_ci
612b1994897Sopenharmony_ciclass ProtoItem;
613b1994897Sopenharmony_ciclass CodeItem;
614b1994897Sopenharmony_ci
615b1994897Sopenharmony_ciclass LineNumberProgramItem : public IndexedItem {
616b1994897Sopenharmony_cipublic:
617b1994897Sopenharmony_ci    enum class Opcode : uint8_t {
618b1994897Sopenharmony_ci        END_SEQUENCE = 0x00,
619b1994897Sopenharmony_ci        ADVANCE_PC = 0x01,
620b1994897Sopenharmony_ci        ADVANCE_LINE = 0x02,
621b1994897Sopenharmony_ci        START_LOCAL = 0x03,
622b1994897Sopenharmony_ci        START_LOCAL_EXTENDED = 0x04,
623b1994897Sopenharmony_ci        END_LOCAL = 0x05,
624b1994897Sopenharmony_ci        RESTART_LOCAL = 0x06,
625b1994897Sopenharmony_ci        SET_PROLOGUE_END = 0x07,
626b1994897Sopenharmony_ci        SET_EPILOGUE_BEGIN = 0x08,
627b1994897Sopenharmony_ci        SET_FILE = 0x09,
628b1994897Sopenharmony_ci        SET_SOURCE_CODE = 0x0a,
629b1994897Sopenharmony_ci        SET_COLUMN = 0X0b,
630b1994897Sopenharmony_ci        LAST
631b1994897Sopenharmony_ci    };
632b1994897Sopenharmony_ci
633b1994897Sopenharmony_ci    static constexpr uint8_t OPCODE_BASE = static_cast<uint8_t>(Opcode::LAST);
634b1994897Sopenharmony_ci    static constexpr int32_t LINE_RANGE = 15;
635b1994897Sopenharmony_ci    static constexpr int32_t LINE_BASE = -4;
636b1994897Sopenharmony_ci
637b1994897Sopenharmony_ci    explicit LineNumberProgramItem(ItemContainer *container) : IndexedItem(container) {}
638b1994897Sopenharmony_ci
639b1994897Sopenharmony_ci    void EmitEnd();
640b1994897Sopenharmony_ci
641b1994897Sopenharmony_ci    void EmitAdvancePc(std::vector<uint8_t> *constant_pool, uint32_t value);
642b1994897Sopenharmony_ci
643b1994897Sopenharmony_ci    void EmitAdvanceLine(std::vector<uint8_t> *constant_pool, int32_t value);
644b1994897Sopenharmony_ci
645b1994897Sopenharmony_ci    void EmitColumn(std::vector<uint8_t> *constant_pool, uint32_t pc_inc, uint32_t column);
646b1994897Sopenharmony_ci
647b1994897Sopenharmony_ci    void EmitStartLocal(std::vector<uint8_t> *constant_pool, int32_t register_number, StringItem *name,
648b1994897Sopenharmony_ci                        StringItem *type);
649b1994897Sopenharmony_ci
650b1994897Sopenharmony_ci    void EmitStartLocalExtended(std::vector<uint8_t> *constant_pool, int32_t register_number, StringItem *name,
651b1994897Sopenharmony_ci                                StringItem *type, StringItem *type_signature);
652b1994897Sopenharmony_ci
653b1994897Sopenharmony_ci    void EmitEndLocal(int32_t register_number);
654b1994897Sopenharmony_ci
655b1994897Sopenharmony_ci    void EmitRestartLocal(int32_t register_number);
656b1994897Sopenharmony_ci
657b1994897Sopenharmony_ci    bool EmitSpecialOpcode(uint32_t pc_inc, int32_t line_inc);
658b1994897Sopenharmony_ci
659b1994897Sopenharmony_ci    void EmitPrologEnd();
660b1994897Sopenharmony_ci
661b1994897Sopenharmony_ci    void EmitEpilogBegin();
662b1994897Sopenharmony_ci
663b1994897Sopenharmony_ci    void EmitSetFile(std::vector<uint8_t> *constant_pool, StringItem *source_file);
664b1994897Sopenharmony_ci
665b1994897Sopenharmony_ci    void EmitSetSourceCode(std::vector<uint8_t> *constant_pool, StringItem *source_code);
666b1994897Sopenharmony_ci
667b1994897Sopenharmony_ci    bool Write(Writer *writer) override;
668b1994897Sopenharmony_ci
669b1994897Sopenharmony_ci    size_t CalculateSize() const override;
670b1994897Sopenharmony_ci
671b1994897Sopenharmony_ci    ItemTypes GetItemType() const override
672b1994897Sopenharmony_ci    {
673b1994897Sopenharmony_ci        return ItemTypes::LINE_NUMBER_PROGRAM_ITEM;
674b1994897Sopenharmony_ci    }
675b1994897Sopenharmony_ci
676b1994897Sopenharmony_ci    const std::vector<uint8_t> &GetData() const
677b1994897Sopenharmony_ci    {
678b1994897Sopenharmony_ci        return data_;
679b1994897Sopenharmony_ci    }
680b1994897Sopenharmony_ci
681b1994897Sopenharmony_ci    IndexType GetIndexType() const override
682b1994897Sopenharmony_ci    {
683b1994897Sopenharmony_ci        return IndexType::LINE_NUMBER_PROG;
684b1994897Sopenharmony_ci    }
685b1994897Sopenharmony_ci
686b1994897Sopenharmony_ci    void SetData(std::vector<uint8_t> &&data);
687b1994897Sopenharmony_ci
688b1994897Sopenharmony_ciprivate:
689b1994897Sopenharmony_ci    void EmitOpcode(Opcode opcode);
690b1994897Sopenharmony_ci    void EmitRegister(int32_t register_number);
691b1994897Sopenharmony_ci
692b1994897Sopenharmony_ci    static void EmitUleb128(std::vector<uint8_t> *data, uint32_t value);
693b1994897Sopenharmony_ci
694b1994897Sopenharmony_ci    static void EmitSleb128(std::vector<uint8_t> *data, int32_t value);
695b1994897Sopenharmony_ci
696b1994897Sopenharmony_ci    std::vector<uint8_t> data_;
697b1994897Sopenharmony_ci};
698b1994897Sopenharmony_ci
699b1994897Sopenharmony_ciclass DebugInfoItem : public BaseItem {
700b1994897Sopenharmony_cipublic:
701b1994897Sopenharmony_ci    explicit DebugInfoItem(LineNumberProgramItem *item) : program_(item) {}
702b1994897Sopenharmony_ci
703b1994897Sopenharmony_ci    ~DebugInfoItem() override = default;
704b1994897Sopenharmony_ci
705b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(DebugInfoItem);
706b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(DebugInfoItem);
707b1994897Sopenharmony_ci
708b1994897Sopenharmony_ci    size_t GetLineNumber() const
709b1994897Sopenharmony_ci    {
710b1994897Sopenharmony_ci        return line_num_;
711b1994897Sopenharmony_ci    }
712b1994897Sopenharmony_ci
713b1994897Sopenharmony_ci    void SetLineNumber(size_t line_num)
714b1994897Sopenharmony_ci    {
715b1994897Sopenharmony_ci        line_num_ = line_num;
716b1994897Sopenharmony_ci    }
717b1994897Sopenharmony_ci
718b1994897Sopenharmony_ci    LineNumberProgramItem *GetLineNumberProgram() const
719b1994897Sopenharmony_ci    {
720b1994897Sopenharmony_ci        return program_;
721b1994897Sopenharmony_ci    }
722b1994897Sopenharmony_ci
723b1994897Sopenharmony_ci    void SetLineNumberProgram(LineNumberProgramItem *program)
724b1994897Sopenharmony_ci    {
725b1994897Sopenharmony_ci        ASSERT(program->GetOffset() != 0);
726b1994897Sopenharmony_ci        program_ = program;
727b1994897Sopenharmony_ci    }
728b1994897Sopenharmony_ci
729b1994897Sopenharmony_ci    void AddParameter(StringItem *name)
730b1994897Sopenharmony_ci    {
731b1994897Sopenharmony_ci        parameters_.push_back(name);
732b1994897Sopenharmony_ci    }
733b1994897Sopenharmony_ci
734b1994897Sopenharmony_ci    std::vector<uint8_t> *GetConstantPool()
735b1994897Sopenharmony_ci    {
736b1994897Sopenharmony_ci        return &constant_pool_;
737b1994897Sopenharmony_ci    }
738b1994897Sopenharmony_ci
739b1994897Sopenharmony_ci    size_t CalculateSize() const override;
740b1994897Sopenharmony_ci
741b1994897Sopenharmony_ci    bool Write(Writer *writer) override;
742b1994897Sopenharmony_ci
743b1994897Sopenharmony_ci    ItemTypes GetItemType() const override
744b1994897Sopenharmony_ci    {
745b1994897Sopenharmony_ci        return ItemTypes::DEBUG_INFO_ITEM;
746b1994897Sopenharmony_ci    }
747b1994897Sopenharmony_ci
748b1994897Sopenharmony_ci    void Dump(std::ostream &os) const override;
749b1994897Sopenharmony_ci
750b1994897Sopenharmony_ciprivate:
751b1994897Sopenharmony_ci    size_t line_num_ {0};
752b1994897Sopenharmony_ci    LineNumberProgramItem *program_;
753b1994897Sopenharmony_ci    std::vector<uint8_t> constant_pool_;
754b1994897Sopenharmony_ci    std::vector<StringItem *> parameters_;
755b1994897Sopenharmony_ci};
756b1994897Sopenharmony_ci
757b1994897Sopenharmony_ciclass BaseMethodItem : public IndexedItem {
758b1994897Sopenharmony_cipublic:
759b1994897Sopenharmony_ci    ProtoItem *GetProto() const
760b1994897Sopenharmony_ci    {
761b1994897Sopenharmony_ci        return proto_;
762b1994897Sopenharmony_ci    }
763b1994897Sopenharmony_ci
764b1994897Sopenharmony_ci    bool IsStatic() const
765b1994897Sopenharmony_ci    {
766b1994897Sopenharmony_ci        return (access_flags_ & ACC_STATIC) != 0;
767b1994897Sopenharmony_ci    }
768b1994897Sopenharmony_ci
769b1994897Sopenharmony_ci    IndexType GetIndexType() const override
770b1994897Sopenharmony_ci    {
771b1994897Sopenharmony_ci        return IndexType::METHOD_STRING_LITERAL;
772b1994897Sopenharmony_ci    }
773b1994897Sopenharmony_ci
774b1994897Sopenharmony_ci    StringItem *GetNameItem() const
775b1994897Sopenharmony_ci    {
776b1994897Sopenharmony_ci        return name_;
777b1994897Sopenharmony_ci    }
778b1994897Sopenharmony_ci
779b1994897Sopenharmony_ci    BaseClassItem *GetClassItem() const
780b1994897Sopenharmony_ci    {
781b1994897Sopenharmony_ci        return class_;
782b1994897Sopenharmony_ci    }
783b1994897Sopenharmony_ci
784b1994897Sopenharmony_ci    void SetFunctionKind(FunctionKind kind)
785b1994897Sopenharmony_ci    {
786b1994897Sopenharmony_ci        access_flags_ &= (~FUNCTION_KIND_MASK);
787b1994897Sopenharmony_ci        access_flags_ |= (static_cast<uint32_t>(kind) << FLAG_WIDTH);
788b1994897Sopenharmony_ci    }
789b1994897Sopenharmony_ci
790b1994897Sopenharmony_ci    void SetHeaderIndex(uint16_t idx)
791b1994897Sopenharmony_ci    {
792b1994897Sopenharmony_ci        access_flags_ &= (FUNCTION_KIND_MASK | FLAG_MASK);
793b1994897Sopenharmony_ci        access_flags_ |= (static_cast<uint32_t>(idx) << (FUNTION_KIND_WIDTH + FLAG_WIDTH));
794b1994897Sopenharmony_ci    }
795b1994897Sopenharmony_ci
796b1994897Sopenharmony_ci    ~BaseMethodItem() override = default;
797b1994897Sopenharmony_ci
798b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(BaseMethodItem);
799b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(BaseMethodItem);
800b1994897Sopenharmony_ci
801b1994897Sopenharmony_ciprotected:
802b1994897Sopenharmony_ci    BaseMethodItem(BaseClassItem *cls, StringItem *name, ProtoItem *proto, uint32_t access_flags,
803b1994897Sopenharmony_ci        ItemContainer *container);
804b1994897Sopenharmony_ci
805b1994897Sopenharmony_ci    size_t CalculateSize() const override;
806b1994897Sopenharmony_ci
807b1994897Sopenharmony_ci    bool Write(Writer *writer) override;
808b1994897Sopenharmony_ci
809b1994897Sopenharmony_ciprivate:
810b1994897Sopenharmony_ci    BaseClassItem *class_;
811b1994897Sopenharmony_ci    StringItem *name_;
812b1994897Sopenharmony_ci    ProtoItem *proto_;
813b1994897Sopenharmony_ci    uint32_t access_flags_;  // layout: |<- 16-bit header index ->|<- 8-bit FunctionKind ->|<- 8-bit flag ->|
814b1994897Sopenharmony_ci};
815b1994897Sopenharmony_ci
816b1994897Sopenharmony_ciclass MethodParamItem {
817b1994897Sopenharmony_cipublic:
818b1994897Sopenharmony_ci    explicit MethodParamItem(TypeItem *type) : type_(type) {}
819b1994897Sopenharmony_ci
820b1994897Sopenharmony_ci    ~MethodParamItem() = default;
821b1994897Sopenharmony_ci
822b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(MethodParamItem);
823b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(MethodParamItem);
824b1994897Sopenharmony_ci
825b1994897Sopenharmony_ci    void AddRuntimeAnnotation(AnnotationItem *runtime_annotation)
826b1994897Sopenharmony_ci    {
827b1994897Sopenharmony_ci        runtime_annotations_.push_back(runtime_annotation);
828b1994897Sopenharmony_ci    }
829b1994897Sopenharmony_ci
830b1994897Sopenharmony_ci    void AddAnnotation(AnnotationItem *annotation)
831b1994897Sopenharmony_ci    {
832b1994897Sopenharmony_ci        annotations_.push_back(annotation);
833b1994897Sopenharmony_ci    }
834b1994897Sopenharmony_ci
835b1994897Sopenharmony_ci    void AddRuntimeTypeAnnotation(AnnotationItem *runtime_type_annotation)
836b1994897Sopenharmony_ci    {
837b1994897Sopenharmony_ci        runtime_type_annotations_.push_back(runtime_type_annotation);
838b1994897Sopenharmony_ci    }
839b1994897Sopenharmony_ci
840b1994897Sopenharmony_ci    void AddTypeAnnotation(AnnotationItem *type_annotation)
841b1994897Sopenharmony_ci    {
842b1994897Sopenharmony_ci        type_annotations_.push_back(type_annotation);
843b1994897Sopenharmony_ci    }
844b1994897Sopenharmony_ci
845b1994897Sopenharmony_ci    TypeItem *GetType() const
846b1994897Sopenharmony_ci    {
847b1994897Sopenharmony_ci        return type_;
848b1994897Sopenharmony_ci    }
849b1994897Sopenharmony_ci
850b1994897Sopenharmony_ci    const std::vector<AnnotationItem *> &GetRuntimeAnnotations() const
851b1994897Sopenharmony_ci    {
852b1994897Sopenharmony_ci        return runtime_annotations_;
853b1994897Sopenharmony_ci    }
854b1994897Sopenharmony_ci
855b1994897Sopenharmony_ci    const std::vector<AnnotationItem *> &GetAnnotations() const
856b1994897Sopenharmony_ci    {
857b1994897Sopenharmony_ci        return annotations_;
858b1994897Sopenharmony_ci    }
859b1994897Sopenharmony_ci
860b1994897Sopenharmony_ci    bool HasAnnotations() const
861b1994897Sopenharmony_ci    {
862b1994897Sopenharmony_ci        return !annotations_.empty();
863b1994897Sopenharmony_ci    }
864b1994897Sopenharmony_ci
865b1994897Sopenharmony_ci    bool HasRuntimeAnnotations() const
866b1994897Sopenharmony_ci    {
867b1994897Sopenharmony_ci        return !runtime_annotations_.empty();
868b1994897Sopenharmony_ci    }
869b1994897Sopenharmony_ci
870b1994897Sopenharmony_ciprivate:
871b1994897Sopenharmony_ci    TypeItem *type_;
872b1994897Sopenharmony_ci    std::vector<AnnotationItem *> runtime_annotations_;
873b1994897Sopenharmony_ci    std::vector<AnnotationItem *> annotations_;
874b1994897Sopenharmony_ci    std::vector<AnnotationItem *> type_annotations_;
875b1994897Sopenharmony_ci    std::vector<AnnotationItem *> runtime_type_annotations_;
876b1994897Sopenharmony_ci};
877b1994897Sopenharmony_ci
878b1994897Sopenharmony_ciclass ParamAnnotationsItem;
879b1994897Sopenharmony_ciclass BaseClassItem;
880b1994897Sopenharmony_ci
881b1994897Sopenharmony_ciclass MethodItem : public BaseMethodItem {
882b1994897Sopenharmony_cipublic:
883b1994897Sopenharmony_ci    MethodItem(ClassItem *cls, StringItem *name, ProtoItem *proto, uint32_t access_flags,
884b1994897Sopenharmony_ci               std::vector<MethodParamItem> params, ItemContainer *container);
885b1994897Sopenharmony_ci
886b1994897Sopenharmony_ci    ~MethodItem() override = default;
887b1994897Sopenharmony_ci
888b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(MethodItem);
889b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(MethodItem);
890b1994897Sopenharmony_ci
891b1994897Sopenharmony_ci    void SetSourceLang(SourceLang lang)
892b1994897Sopenharmony_ci    {
893b1994897Sopenharmony_ci        source_lang_ = lang;
894b1994897Sopenharmony_ci    }
895b1994897Sopenharmony_ci
896b1994897Sopenharmony_ci    void SetCode(CodeItem *code)
897b1994897Sopenharmony_ci    {
898b1994897Sopenharmony_ci        code_ = code;
899b1994897Sopenharmony_ci    }
900b1994897Sopenharmony_ci
901b1994897Sopenharmony_ci    void SetDebugInfo(DebugInfoItem *debug_info)
902b1994897Sopenharmony_ci    {
903b1994897Sopenharmony_ci        debug_info_ = debug_info;
904b1994897Sopenharmony_ci    }
905b1994897Sopenharmony_ci
906b1994897Sopenharmony_ci    void AddRuntimeAnnotation(AnnotationItem *runtime_annotation)
907b1994897Sopenharmony_ci    {
908b1994897Sopenharmony_ci        runtime_annotations_.push_back(runtime_annotation);
909b1994897Sopenharmony_ci    }
910b1994897Sopenharmony_ci
911b1994897Sopenharmony_ci    void AddAnnotation(AnnotationItem *annotation)
912b1994897Sopenharmony_ci    {
913b1994897Sopenharmony_ci        annotations_.push_back(annotation);
914b1994897Sopenharmony_ci    }
915b1994897Sopenharmony_ci
916b1994897Sopenharmony_ci    void AddRuntimeTypeAnnotation(AnnotationItem *runtime_type_annotation)
917b1994897Sopenharmony_ci    {
918b1994897Sopenharmony_ci        runtime_type_annotations_.push_back(runtime_type_annotation);
919b1994897Sopenharmony_ci    }
920b1994897Sopenharmony_ci
921b1994897Sopenharmony_ci    void AddTypeAnnotation(AnnotationItem *type_annotation)
922b1994897Sopenharmony_ci    {
923b1994897Sopenharmony_ci        type_annotations_.push_back(type_annotation);
924b1994897Sopenharmony_ci    }
925b1994897Sopenharmony_ci
926b1994897Sopenharmony_ci    void SetRuntimeParamAnnotationItem(ParamAnnotationsItem *annotations)
927b1994897Sopenharmony_ci    {
928b1994897Sopenharmony_ci        runtime_param_annotations_ = annotations;
929b1994897Sopenharmony_ci    }
930b1994897Sopenharmony_ci
931b1994897Sopenharmony_ci    void SetParamAnnotationItem(ParamAnnotationsItem *annotations)
932b1994897Sopenharmony_ci    {
933b1994897Sopenharmony_ci        param_annotations_ = annotations;
934b1994897Sopenharmony_ci    }
935b1994897Sopenharmony_ci
936b1994897Sopenharmony_ci    bool HasRuntimeParamAnnotations() const
937b1994897Sopenharmony_ci    {
938b1994897Sopenharmony_ci        return std::any_of(params_.cbegin(), params_.cend(),
939b1994897Sopenharmony_ci                           [](const MethodParamItem &item) { return item.HasRuntimeAnnotations(); });
940b1994897Sopenharmony_ci    }
941b1994897Sopenharmony_ci
942b1994897Sopenharmony_ci    bool HasParamAnnotations() const
943b1994897Sopenharmony_ci    {
944b1994897Sopenharmony_ci        return std::any_of(params_.cbegin(), params_.cend(),
945b1994897Sopenharmony_ci                           [](const MethodParamItem &item) { return item.HasAnnotations(); });
946b1994897Sopenharmony_ci    }
947b1994897Sopenharmony_ci
948b1994897Sopenharmony_ci    CodeItem *GetCode() const
949b1994897Sopenharmony_ci    {
950b1994897Sopenharmony_ci        return code_;
951b1994897Sopenharmony_ci    }
952b1994897Sopenharmony_ci
953b1994897Sopenharmony_ci    DebugInfoItem *GetDebugInfo() const
954b1994897Sopenharmony_ci    {
955b1994897Sopenharmony_ci        return debug_info_;
956b1994897Sopenharmony_ci    }
957b1994897Sopenharmony_ci
958b1994897Sopenharmony_ci    size_t CalculateSize() const override;
959b1994897Sopenharmony_ci
960b1994897Sopenharmony_ci    bool Write(Writer *writer) override;
961b1994897Sopenharmony_ci
962b1994897Sopenharmony_ci    ItemTypes GetItemType() const override
963b1994897Sopenharmony_ci    {
964b1994897Sopenharmony_ci        return ItemTypes::METHOD_ITEM;
965b1994897Sopenharmony_ci    }
966b1994897Sopenharmony_ci
967b1994897Sopenharmony_ci    std::vector<MethodParamItem> &GetParams()
968b1994897Sopenharmony_ci    {
969b1994897Sopenharmony_ci        return params_;
970b1994897Sopenharmony_ci    }
971b1994897Sopenharmony_ci
972b1994897Sopenharmony_ci    std::vector<AnnotationItem *> *GetRuntimeAnnotations()
973b1994897Sopenharmony_ci    {
974b1994897Sopenharmony_ci        return &runtime_annotations_;
975b1994897Sopenharmony_ci    }
976b1994897Sopenharmony_ci
977b1994897Sopenharmony_ci    std::vector<AnnotationItem *> *GetAnnotations()
978b1994897Sopenharmony_ci    {
979b1994897Sopenharmony_ci        return &annotations_;
980b1994897Sopenharmony_ci    }
981b1994897Sopenharmony_ci
982b1994897Sopenharmony_ci    std::vector<AnnotationItem *> *GetTypeAnnotations()
983b1994897Sopenharmony_ci    {
984b1994897Sopenharmony_ci        return &type_annotations_;
985b1994897Sopenharmony_ci    }
986b1994897Sopenharmony_ci
987b1994897Sopenharmony_ci    std::vector<AnnotationItem *> *GetRuntimeTypeAnnotations()
988b1994897Sopenharmony_ci    {
989b1994897Sopenharmony_ci        return &runtime_type_annotations_;
990b1994897Sopenharmony_ci    }
991b1994897Sopenharmony_ci
992b1994897Sopenharmony_ciprivate:
993b1994897Sopenharmony_ci    bool WriteRuntimeAnnotations(Writer *writer);
994b1994897Sopenharmony_ci
995b1994897Sopenharmony_ci    bool WriteTypeAnnotations(Writer *writer);
996b1994897Sopenharmony_ci
997b1994897Sopenharmony_ci    bool WriteTaggedData(Writer *writer);
998b1994897Sopenharmony_ci
999b1994897Sopenharmony_ci    std::vector<MethodParamItem> params_;
1000b1994897Sopenharmony_ci
1001b1994897Sopenharmony_ci    SourceLang source_lang_;
1002b1994897Sopenharmony_ci    CodeItem *code_;
1003b1994897Sopenharmony_ci    DebugInfoItem *debug_info_;
1004b1994897Sopenharmony_ci    std::vector<AnnotationItem *> runtime_annotations_;
1005b1994897Sopenharmony_ci    std::vector<AnnotationItem *> annotations_;
1006b1994897Sopenharmony_ci    std::vector<AnnotationItem *> type_annotations_;
1007b1994897Sopenharmony_ci    std::vector<AnnotationItem *> runtime_type_annotations_;
1008b1994897Sopenharmony_ci    ParamAnnotationsItem *runtime_param_annotations_ {nullptr};
1009b1994897Sopenharmony_ci    ParamAnnotationsItem *param_annotations_ {nullptr};
1010b1994897Sopenharmony_ci};
1011b1994897Sopenharmony_ci
1012b1994897Sopenharmony_ciclass BaseClassItem : public TypeItem {
1013b1994897Sopenharmony_cipublic:
1014b1994897Sopenharmony_ci    StringItem *GetNameItem()
1015b1994897Sopenharmony_ci    {
1016b1994897Sopenharmony_ci        return &name_;
1017b1994897Sopenharmony_ci    }
1018b1994897Sopenharmony_ci
1019b1994897Sopenharmony_ciprotected:
1020b1994897Sopenharmony_ci    explicit BaseClassItem(const std::string &name, ItemContainer *container)
1021b1994897Sopenharmony_ci        : TypeItem(Type::TypeId::REFERENCE, container), name_(name, container) {}
1022b1994897Sopenharmony_ci
1023b1994897Sopenharmony_ci    ~BaseClassItem() override = default;
1024b1994897Sopenharmony_ci
1025b1994897Sopenharmony_ci    size_t CalculateSize() const override;
1026b1994897Sopenharmony_ci
1027b1994897Sopenharmony_ci    void ComputeLayout() override;
1028b1994897Sopenharmony_ci
1029b1994897Sopenharmony_ci    bool Write(Writer *writer) override;
1030b1994897Sopenharmony_ci
1031b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(BaseClassItem);
1032b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(BaseClassItem);
1033b1994897Sopenharmony_ci
1034b1994897Sopenharmony_ciprivate:
1035b1994897Sopenharmony_ci    StringItem name_;
1036b1994897Sopenharmony_ci};
1037b1994897Sopenharmony_ci
1038b1994897Sopenharmony_ciclass ClassItem : public BaseClassItem {
1039b1994897Sopenharmony_cipublic:
1040b1994897Sopenharmony_ci    explicit ClassItem(const std::string &name, ItemContainer *container)
1041b1994897Sopenharmony_ci        : BaseClassItem(name, container),
1042b1994897Sopenharmony_ci          super_class_(nullptr),
1043b1994897Sopenharmony_ci          access_flags_(0),
1044b1994897Sopenharmony_ci          source_lang_(SourceLang::PANDA_ASSEMBLY),
1045b1994897Sopenharmony_ci          source_file_(nullptr),
1046b1994897Sopenharmony_ci          container_(container)
1047b1994897Sopenharmony_ci    {
1048b1994897Sopenharmony_ci    }
1049b1994897Sopenharmony_ci
1050b1994897Sopenharmony_ci    ~ClassItem() override = default;
1051b1994897Sopenharmony_ci
1052b1994897Sopenharmony_ci    void SetAccessFlags(uint32_t access_flags)
1053b1994897Sopenharmony_ci    {
1054b1994897Sopenharmony_ci        access_flags_ = access_flags;
1055b1994897Sopenharmony_ci    }
1056b1994897Sopenharmony_ci
1057b1994897Sopenharmony_ci    void SetSourceLang(SourceLang lang)
1058b1994897Sopenharmony_ci    {
1059b1994897Sopenharmony_ci        source_lang_ = lang;
1060b1994897Sopenharmony_ci    }
1061b1994897Sopenharmony_ci
1062b1994897Sopenharmony_ci    void SetSuperClass(BaseClassItem *super_class)
1063b1994897Sopenharmony_ci    {
1064b1994897Sopenharmony_ci        super_class_ = super_class;
1065b1994897Sopenharmony_ci    }
1066b1994897Sopenharmony_ci
1067b1994897Sopenharmony_ci    void AddInterface(BaseClassItem *iface)
1068b1994897Sopenharmony_ci    {
1069b1994897Sopenharmony_ci        AddIndexDependency(iface);
1070b1994897Sopenharmony_ci        ifaces_.push_back(iface);
1071b1994897Sopenharmony_ci    }
1072b1994897Sopenharmony_ci
1073b1994897Sopenharmony_ci    void AddRuntimeAnnotation(AnnotationItem *runtime_annotation)
1074b1994897Sopenharmony_ci    {
1075b1994897Sopenharmony_ci        runtime_annotations_.push_back(runtime_annotation);
1076b1994897Sopenharmony_ci    }
1077b1994897Sopenharmony_ci
1078b1994897Sopenharmony_ci    void AddAnnotation(AnnotationItem *annotation)
1079b1994897Sopenharmony_ci    {
1080b1994897Sopenharmony_ci        annotations_.push_back(annotation);
1081b1994897Sopenharmony_ci    }
1082b1994897Sopenharmony_ci
1083b1994897Sopenharmony_ci    void AddRuntimeTypeAnnotation(AnnotationItem *runtime_type_annotation)
1084b1994897Sopenharmony_ci    {
1085b1994897Sopenharmony_ci        runtime_type_annotations_.push_back(runtime_type_annotation);
1086b1994897Sopenharmony_ci    }
1087b1994897Sopenharmony_ci
1088b1994897Sopenharmony_ci    void AddTypeAnnotation(AnnotationItem *type_annotation)
1089b1994897Sopenharmony_ci    {
1090b1994897Sopenharmony_ci        type_annotations_.push_back(type_annotation);
1091b1994897Sopenharmony_ci    }
1092b1994897Sopenharmony_ci
1093b1994897Sopenharmony_ci    template <class... Args>
1094b1994897Sopenharmony_ci    FieldItem *AddField(Args... args)
1095b1994897Sopenharmony_ci    {
1096b1994897Sopenharmony_ci        fields_.emplace_back(std::make_unique<FieldItem>(this, std::forward<Args>(args)..., container_));
1097b1994897Sopenharmony_ci        return fields_.back().get();
1098b1994897Sopenharmony_ci    }
1099b1994897Sopenharmony_ci
1100b1994897Sopenharmony_ci    template <class... Args>
1101b1994897Sopenharmony_ci    MethodItem *AddMethod(Args... args)
1102b1994897Sopenharmony_ci    {
1103b1994897Sopenharmony_ci        // insert new method to set ordered by method name
1104b1994897Sopenharmony_ci        return methods_.insert(std::make_unique<MethodItem>(this, std::forward<Args>(args)..., container_))->get();
1105b1994897Sopenharmony_ci    }
1106b1994897Sopenharmony_ci
1107b1994897Sopenharmony_ci    void SetSourceFile(StringItem *item)
1108b1994897Sopenharmony_ci    {
1109b1994897Sopenharmony_ci        source_file_ = item;
1110b1994897Sopenharmony_ci    }
1111b1994897Sopenharmony_ci
1112b1994897Sopenharmony_ci    size_t CalculateSizeWithoutFieldsAndMethods() const;
1113b1994897Sopenharmony_ci
1114b1994897Sopenharmony_ci    size_t CalculateSize() const override;
1115b1994897Sopenharmony_ci
1116b1994897Sopenharmony_ci    void ComputeLayout() override;
1117b1994897Sopenharmony_ci
1118b1994897Sopenharmony_ci    bool Write(Writer *writer) override;
1119b1994897Sopenharmony_ci
1120b1994897Sopenharmony_ci    ItemTypes GetItemType() const override
1121b1994897Sopenharmony_ci    {
1122b1994897Sopenharmony_ci        return ItemTypes::CLASS_ITEM;
1123b1994897Sopenharmony_ci    }
1124b1994897Sopenharmony_ci
1125b1994897Sopenharmony_ci    void VisitFields(const VisitorCallBack &cb)
1126b1994897Sopenharmony_ci    {
1127b1994897Sopenharmony_ci        for (auto &field : fields_) {
1128b1994897Sopenharmony_ci            if (!cb(field.get())) {
1129b1994897Sopenharmony_ci                break;
1130b1994897Sopenharmony_ci            }
1131b1994897Sopenharmony_ci        }
1132b1994897Sopenharmony_ci    }
1133b1994897Sopenharmony_ci
1134b1994897Sopenharmony_ci    void VisitMethods(const VisitorCallBack &cb)
1135b1994897Sopenharmony_ci    {
1136b1994897Sopenharmony_ci        for (auto &method : methods_) {
1137b1994897Sopenharmony_ci            if (!cb(method.get())) {
1138b1994897Sopenharmony_ci                break;
1139b1994897Sopenharmony_ci            }
1140b1994897Sopenharmony_ci        }
1141b1994897Sopenharmony_ci    }
1142b1994897Sopenharmony_ci
1143b1994897Sopenharmony_ci    void Visit(const VisitorCallBack &cb) override
1144b1994897Sopenharmony_ci    {
1145b1994897Sopenharmony_ci        VisitFields(cb);
1146b1994897Sopenharmony_ci        VisitMethods(cb);
1147b1994897Sopenharmony_ci    }
1148b1994897Sopenharmony_ci
1149b1994897Sopenharmony_ci    std::vector<AnnotationItem *> *GetRuntimeAnnotations()
1150b1994897Sopenharmony_ci    {
1151b1994897Sopenharmony_ci        return &runtime_annotations_;
1152b1994897Sopenharmony_ci    }
1153b1994897Sopenharmony_ci
1154b1994897Sopenharmony_ci    std::vector<AnnotationItem *> *GetAnnotations()
1155b1994897Sopenharmony_ci    {
1156b1994897Sopenharmony_ci        return &annotations_;
1157b1994897Sopenharmony_ci    }
1158b1994897Sopenharmony_ci
1159b1994897Sopenharmony_ci    std::vector<AnnotationItem *> *GetTypeAnnotations()
1160b1994897Sopenharmony_ci    {
1161b1994897Sopenharmony_ci        return &type_annotations_;
1162b1994897Sopenharmony_ci    }
1163b1994897Sopenharmony_ci
1164b1994897Sopenharmony_ci    std::vector<AnnotationItem *> *GetRuntimeTypeAnnotations()
1165b1994897Sopenharmony_ci    {
1166b1994897Sopenharmony_ci        return &runtime_type_annotations_;
1167b1994897Sopenharmony_ci    }
1168b1994897Sopenharmony_ci
1169b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(ClassItem);
1170b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(ClassItem);
1171b1994897Sopenharmony_ci
1172b1994897Sopenharmony_ciprivate:
1173b1994897Sopenharmony_ci    struct MethodCompByName {
1174b1994897Sopenharmony_ci        bool operator()(const std::unique_ptr<MethodItem> &m1, const std::unique_ptr<MethodItem> &m2) const
1175b1994897Sopenharmony_ci        {
1176b1994897Sopenharmony_ci            auto *str1 = m1->GetNameItem();
1177b1994897Sopenharmony_ci            auto *str2 = m2->GetNameItem();
1178b1994897Sopenharmony_ci            if (str1->GetUtf16Len() == str2->GetUtf16Len()) {
1179b1994897Sopenharmony_ci                return str1->GetData() < str2->GetData();
1180b1994897Sopenharmony_ci            }
1181b1994897Sopenharmony_ci            return str1->GetUtf16Len() < str2->GetUtf16Len();
1182b1994897Sopenharmony_ci        }
1183b1994897Sopenharmony_ci    };
1184b1994897Sopenharmony_ci
1185b1994897Sopenharmony_ci    bool WriteIfaces(Writer *writer);
1186b1994897Sopenharmony_ci
1187b1994897Sopenharmony_ci    bool WriteAnnotations(Writer *writer);
1188b1994897Sopenharmony_ci
1189b1994897Sopenharmony_ci    bool WriteTaggedData(Writer *writer);
1190b1994897Sopenharmony_ci
1191b1994897Sopenharmony_ci    BaseClassItem *super_class_;
1192b1994897Sopenharmony_ci    uint32_t access_flags_;
1193b1994897Sopenharmony_ci    SourceLang source_lang_;
1194b1994897Sopenharmony_ci    std::vector<BaseClassItem *> ifaces_;
1195b1994897Sopenharmony_ci    std::vector<AnnotationItem *> runtime_annotations_;
1196b1994897Sopenharmony_ci    std::vector<AnnotationItem *> annotations_;
1197b1994897Sopenharmony_ci    std::vector<AnnotationItem *> type_annotations_;
1198b1994897Sopenharmony_ci    std::vector<AnnotationItem *> runtime_type_annotations_;
1199b1994897Sopenharmony_ci    StringItem *source_file_;
1200b1994897Sopenharmony_ci    std::vector<std::unique_ptr<FieldItem>> fields_;
1201b1994897Sopenharmony_ci    std::multiset<std::unique_ptr<MethodItem>, MethodCompByName> methods_;
1202b1994897Sopenharmony_ci    ItemContainer *container_;
1203b1994897Sopenharmony_ci};
1204b1994897Sopenharmony_ci
1205b1994897Sopenharmony_ciclass ForeignClassItem : public BaseClassItem {
1206b1994897Sopenharmony_cipublic:
1207b1994897Sopenharmony_ci    explicit ForeignClassItem(const std::string &name, ItemContainer *container) : BaseClassItem(name, container) {}
1208b1994897Sopenharmony_ci
1209b1994897Sopenharmony_ci    ~ForeignClassItem() override = default;
1210b1994897Sopenharmony_ci
1211b1994897Sopenharmony_ci    bool IsForeign() const override
1212b1994897Sopenharmony_ci    {
1213b1994897Sopenharmony_ci        return true;
1214b1994897Sopenharmony_ci    }
1215b1994897Sopenharmony_ci
1216b1994897Sopenharmony_ci    ItemTypes GetItemType() const override
1217b1994897Sopenharmony_ci    {
1218b1994897Sopenharmony_ci        return ItemTypes::FOREIGN_CLASS_ITEM;
1219b1994897Sopenharmony_ci    }
1220b1994897Sopenharmony_ci
1221b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(ForeignClassItem);
1222b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(ForeignClassItem);
1223b1994897Sopenharmony_ci};
1224b1994897Sopenharmony_ci
1225b1994897Sopenharmony_ciclass ForeignFieldItem : public BaseFieldItem {
1226b1994897Sopenharmony_cipublic:
1227b1994897Sopenharmony_ci    ForeignFieldItem(BaseClassItem *cls, StringItem *name, TypeItem *type, ItemContainer *container)
1228b1994897Sopenharmony_ci        : BaseFieldItem(cls, name, type, container) {}
1229b1994897Sopenharmony_ci
1230b1994897Sopenharmony_ci    ~ForeignFieldItem() override = default;
1231b1994897Sopenharmony_ci
1232b1994897Sopenharmony_ci    bool IsForeign() const override
1233b1994897Sopenharmony_ci    {
1234b1994897Sopenharmony_ci        return true;
1235b1994897Sopenharmony_ci    }
1236b1994897Sopenharmony_ci
1237b1994897Sopenharmony_ci    ItemTypes GetItemType() const override
1238b1994897Sopenharmony_ci    {
1239b1994897Sopenharmony_ci        return ItemTypes::FOREIGN_FIELD_ITEM;
1240b1994897Sopenharmony_ci    }
1241b1994897Sopenharmony_ci
1242b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(ForeignFieldItem);
1243b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(ForeignFieldItem);
1244b1994897Sopenharmony_ci};
1245b1994897Sopenharmony_ci
1246b1994897Sopenharmony_ciclass ForeignMethodItem : public BaseMethodItem {
1247b1994897Sopenharmony_cipublic:
1248b1994897Sopenharmony_ci    ForeignMethodItem(BaseClassItem *cls, StringItem *name, ProtoItem *proto, uint32_t access_flags,
1249b1994897Sopenharmony_ci        ItemContainer *container) : BaseMethodItem(cls, name, proto, access_flags, container)
1250b1994897Sopenharmony_ci    {
1251b1994897Sopenharmony_ci    }
1252b1994897Sopenharmony_ci
1253b1994897Sopenharmony_ci    ~ForeignMethodItem() override = default;
1254b1994897Sopenharmony_ci
1255b1994897Sopenharmony_ci    bool IsForeign() const override
1256b1994897Sopenharmony_ci    {
1257b1994897Sopenharmony_ci        return true;
1258b1994897Sopenharmony_ci    }
1259b1994897Sopenharmony_ci
1260b1994897Sopenharmony_ci    ItemTypes GetItemType() const override
1261b1994897Sopenharmony_ci    {
1262b1994897Sopenharmony_ci        return ItemTypes::FOREIGN_METHOD_ITEM;
1263b1994897Sopenharmony_ci    }
1264b1994897Sopenharmony_ci
1265b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(ForeignMethodItem);
1266b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(ForeignMethodItem);
1267b1994897Sopenharmony_ci};
1268b1994897Sopenharmony_ci
1269b1994897Sopenharmony_ciclass ProtoItem;
1270b1994897Sopenharmony_ci
1271b1994897Sopenharmony_ciclass ParamAnnotationsItem : public BaseItem {
1272b1994897Sopenharmony_cipublic:
1273b1994897Sopenharmony_ci    ParamAnnotationsItem(MethodItem *method, bool is_runtime_annotations);
1274b1994897Sopenharmony_ci
1275b1994897Sopenharmony_ci    ~ParamAnnotationsItem() override = default;
1276b1994897Sopenharmony_ci
1277b1994897Sopenharmony_ci    ItemTypes GetItemType() const override
1278b1994897Sopenharmony_ci    {
1279b1994897Sopenharmony_ci        return ItemTypes::PARAM_ANNOTATIONS_ITEM;
1280b1994897Sopenharmony_ci    }
1281b1994897Sopenharmony_ci
1282b1994897Sopenharmony_ci    size_t CalculateSize() const override;
1283b1994897Sopenharmony_ci
1284b1994897Sopenharmony_ci    bool Write(Writer *writer) override;
1285b1994897Sopenharmony_ci
1286b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(ParamAnnotationsItem);
1287b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(ParamAnnotationsItem);
1288b1994897Sopenharmony_ci
1289b1994897Sopenharmony_ciprivate:
1290b1994897Sopenharmony_ci    std::vector<std::vector<AnnotationItem *>> annotations_;
1291b1994897Sopenharmony_ci};
1292b1994897Sopenharmony_ci
1293b1994897Sopenharmony_ciclass ProtoItem : public IndexedItem {
1294b1994897Sopenharmony_cipublic:
1295b1994897Sopenharmony_ci    ProtoItem(TypeItem *ret_type, const std::vector<MethodParamItem> &params, ItemContainer *itemContainer);
1296b1994897Sopenharmony_ci
1297b1994897Sopenharmony_ci    ~ProtoItem() override = default;
1298b1994897Sopenharmony_ci
1299b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(ProtoItem);
1300b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(ProtoItem);
1301b1994897Sopenharmony_ci
1302b1994897Sopenharmony_ci    size_t CalculateSize() const override
1303b1994897Sopenharmony_ci    {
1304b1994897Sopenharmony_ci        size_t size = shorty_.size() * sizeof(uint16_t);
1305b1994897Sopenharmony_ci        size += reference_types_.size() * IDX_SIZE;
1306b1994897Sopenharmony_ci        return size;
1307b1994897Sopenharmony_ci    }
1308b1994897Sopenharmony_ci
1309b1994897Sopenharmony_ci    bool Write(Writer *writer) override;
1310b1994897Sopenharmony_ci
1311b1994897Sopenharmony_ci    ItemTypes GetItemType() const override
1312b1994897Sopenharmony_ci    {
1313b1994897Sopenharmony_ci        return ItemTypes::PROTO_ITEM;
1314b1994897Sopenharmony_ci    }
1315b1994897Sopenharmony_ci
1316b1994897Sopenharmony_ci    IndexType GetIndexType() const override
1317b1994897Sopenharmony_ci    {
1318b1994897Sopenharmony_ci        return IndexType::PROTO;
1319b1994897Sopenharmony_ci    }
1320b1994897Sopenharmony_ci
1321b1994897Sopenharmony_ci    size_t Alignment() override
1322b1994897Sopenharmony_ci    {
1323b1994897Sopenharmony_ci        return sizeof(uint16_t);
1324b1994897Sopenharmony_ci    }
1325b1994897Sopenharmony_ci
1326b1994897Sopenharmony_ciprivate:
1327b1994897Sopenharmony_ci    static constexpr size_t SHORTY_ELEM_SIZE = 4;
1328b1994897Sopenharmony_ci
1329b1994897Sopenharmony_ci    void AddType(TypeItem *type, size_t *n);
1330b1994897Sopenharmony_ci
1331b1994897Sopenharmony_ci    std::vector<uint16_t> shorty_;
1332b1994897Sopenharmony_ci    std::vector<TypeItem *> reference_types_;
1333b1994897Sopenharmony_ci};
1334b1994897Sopenharmony_ci
1335b1994897Sopenharmony_ciclass CodeItem : public BaseItem {
1336b1994897Sopenharmony_cipublic:
1337b1994897Sopenharmony_ci    class CatchBlock : public BaseItem {
1338b1994897Sopenharmony_ci    public:
1339b1994897Sopenharmony_ci        CatchBlock(MethodItem *method, BaseClassItem *type, size_t handler_pc, size_t code_size = 0)
1340b1994897Sopenharmony_ci            : method_(method), type_(type), handler_pc_(handler_pc), code_size_(code_size)
1341b1994897Sopenharmony_ci        {
1342b1994897Sopenharmony_ci        }
1343b1994897Sopenharmony_ci
1344b1994897Sopenharmony_ci        ~CatchBlock() override = default;
1345b1994897Sopenharmony_ci
1346b1994897Sopenharmony_ci        DEFAULT_MOVE_SEMANTIC(CatchBlock);
1347b1994897Sopenharmony_ci        DEFAULT_COPY_SEMANTIC(CatchBlock);
1348b1994897Sopenharmony_ci
1349b1994897Sopenharmony_ci        size_t CalculateSize() const override;
1350b1994897Sopenharmony_ci
1351b1994897Sopenharmony_ci        bool Write(Writer *writer) override;
1352b1994897Sopenharmony_ci
1353b1994897Sopenharmony_ci        ItemTypes GetItemType() const override
1354b1994897Sopenharmony_ci        {
1355b1994897Sopenharmony_ci            return ItemTypes::CATCH_BLOCK_ITEM;
1356b1994897Sopenharmony_ci        }
1357b1994897Sopenharmony_ci
1358b1994897Sopenharmony_ci    private:
1359b1994897Sopenharmony_ci        MethodItem *method_;
1360b1994897Sopenharmony_ci        BaseClassItem *type_;
1361b1994897Sopenharmony_ci        size_t handler_pc_;
1362b1994897Sopenharmony_ci        size_t code_size_;
1363b1994897Sopenharmony_ci    };
1364b1994897Sopenharmony_ci
1365b1994897Sopenharmony_ci    class TryBlock : public BaseItem {
1366b1994897Sopenharmony_ci    public:
1367b1994897Sopenharmony_ci        TryBlock(size_t start_pc, size_t length, std::vector<CatchBlock> catch_blocks)
1368b1994897Sopenharmony_ci            : start_pc_(start_pc), length_(length), catch_blocks_(std::move(catch_blocks))
1369b1994897Sopenharmony_ci        {
1370b1994897Sopenharmony_ci        }
1371b1994897Sopenharmony_ci
1372b1994897Sopenharmony_ci        ~TryBlock() override = default;
1373b1994897Sopenharmony_ci
1374b1994897Sopenharmony_ci        DEFAULT_MOVE_SEMANTIC(TryBlock);
1375b1994897Sopenharmony_ci        DEFAULT_COPY_SEMANTIC(TryBlock);
1376b1994897Sopenharmony_ci
1377b1994897Sopenharmony_ci        size_t CalculateSizeWithoutCatchBlocks() const;
1378b1994897Sopenharmony_ci
1379b1994897Sopenharmony_ci        void ComputeLayout() override;
1380b1994897Sopenharmony_ci
1381b1994897Sopenharmony_ci        size_t CalculateSize() const override;
1382b1994897Sopenharmony_ci
1383b1994897Sopenharmony_ci        bool Write(Writer *writer) override;
1384b1994897Sopenharmony_ci
1385b1994897Sopenharmony_ci        ItemTypes GetItemType() const override
1386b1994897Sopenharmony_ci        {
1387b1994897Sopenharmony_ci            return ItemTypes::TRY_BLOCK_ITEM;
1388b1994897Sopenharmony_ci        }
1389b1994897Sopenharmony_ci
1390b1994897Sopenharmony_ci    private:
1391b1994897Sopenharmony_ci        size_t start_pc_;
1392b1994897Sopenharmony_ci        size_t length_;
1393b1994897Sopenharmony_ci        std::vector<CatchBlock> catch_blocks_;
1394b1994897Sopenharmony_ci    };
1395b1994897Sopenharmony_ci
1396b1994897Sopenharmony_ci    CodeItem(size_t num_vregs, size_t num_args, std::vector<uint8_t> instructions)
1397b1994897Sopenharmony_ci        : num_vregs_(num_vregs), num_args_(num_args), instructions_(std::move(instructions))
1398b1994897Sopenharmony_ci    {
1399b1994897Sopenharmony_ci    }
1400b1994897Sopenharmony_ci
1401b1994897Sopenharmony_ci    CodeItem() = default;
1402b1994897Sopenharmony_ci
1403b1994897Sopenharmony_ci    ~CodeItem() override = default;
1404b1994897Sopenharmony_ci
1405b1994897Sopenharmony_ci    void SetNumVregs(size_t num_vregs)
1406b1994897Sopenharmony_ci    {
1407b1994897Sopenharmony_ci        num_vregs_ = num_vregs;
1408b1994897Sopenharmony_ci    }
1409b1994897Sopenharmony_ci
1410b1994897Sopenharmony_ci    void SetNumArgs(size_t num_args)
1411b1994897Sopenharmony_ci    {
1412b1994897Sopenharmony_ci        num_args_ = num_args;
1413b1994897Sopenharmony_ci    }
1414b1994897Sopenharmony_ci
1415b1994897Sopenharmony_ci    std::vector<uint8_t> *GetInstructions()
1416b1994897Sopenharmony_ci    {
1417b1994897Sopenharmony_ci        return &instructions_;
1418b1994897Sopenharmony_ci    }
1419b1994897Sopenharmony_ci
1420b1994897Sopenharmony_ci    void SetNumInstructions(size_t num_ins)
1421b1994897Sopenharmony_ci    {
1422b1994897Sopenharmony_ci        num_ins_ = num_ins;
1423b1994897Sopenharmony_ci    }
1424b1994897Sopenharmony_ci
1425b1994897Sopenharmony_ci    size_t GetNumInstructions() const
1426b1994897Sopenharmony_ci    {
1427b1994897Sopenharmony_ci        return num_ins_;
1428b1994897Sopenharmony_ci    }
1429b1994897Sopenharmony_ci
1430b1994897Sopenharmony_ci    void AddTryBlock(const TryBlock &try_block)
1431b1994897Sopenharmony_ci    {
1432b1994897Sopenharmony_ci        try_blocks_.push_back(try_block);
1433b1994897Sopenharmony_ci    }
1434b1994897Sopenharmony_ci
1435b1994897Sopenharmony_ci    size_t CalculateSizeWithoutTryBlocks() const;
1436b1994897Sopenharmony_ci
1437b1994897Sopenharmony_ci    void ComputeLayout() override;
1438b1994897Sopenharmony_ci
1439b1994897Sopenharmony_ci    size_t CalculateSize() const override;
1440b1994897Sopenharmony_ci
1441b1994897Sopenharmony_ci    size_t GetCodeSize() const;
1442b1994897Sopenharmony_ci
1443b1994897Sopenharmony_ci    bool Write(Writer *writer) override;
1444b1994897Sopenharmony_ci
1445b1994897Sopenharmony_ci    ItemTypes GetItemType() const override
1446b1994897Sopenharmony_ci    {
1447b1994897Sopenharmony_ci        return ItemTypes::CODE_ITEM;
1448b1994897Sopenharmony_ci    }
1449b1994897Sopenharmony_ci
1450b1994897Sopenharmony_ci    void AddMethod(BaseMethodItem *method)
1451b1994897Sopenharmony_ci    {
1452b1994897Sopenharmony_ci        methods_.emplace_back(method);
1453b1994897Sopenharmony_ci    }
1454b1994897Sopenharmony_ci
1455b1994897Sopenharmony_ci    std::vector<std::string> GetMethodNames() const
1456b1994897Sopenharmony_ci    {
1457b1994897Sopenharmony_ci        std::vector<std::string> names;
1458b1994897Sopenharmony_ci        for (const auto *method : methods_) {
1459b1994897Sopenharmony_ci            if (method == nullptr) {
1460b1994897Sopenharmony_ci                continue;
1461b1994897Sopenharmony_ci            }
1462b1994897Sopenharmony_ci            std::string class_name;
1463b1994897Sopenharmony_ci            if (method->GetClassItem() != nullptr) {
1464b1994897Sopenharmony_ci                class_name = method->GetClassItem()->GetNameItem()->GetData();
1465b1994897Sopenharmony_ci                class_name.pop_back();          // remove '\0'
1466b1994897Sopenharmony_ci                ASSERT(class_name.size() > 2);  // 2 - L and ;
1467b1994897Sopenharmony_ci                class_name.erase(0, 1);
1468b1994897Sopenharmony_ci                class_name.pop_back();
1469b1994897Sopenharmony_ci                class_name.append("::");
1470b1994897Sopenharmony_ci            }
1471b1994897Sopenharmony_ci            class_name.append(method->GetNameItem()->GetData());
1472b1994897Sopenharmony_ci            class_name.pop_back();  // remove '\0'
1473b1994897Sopenharmony_ci            names.emplace_back(class_name);
1474b1994897Sopenharmony_ci        }
1475b1994897Sopenharmony_ci        return names;
1476b1994897Sopenharmony_ci    }
1477b1994897Sopenharmony_ci
1478b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(CodeItem);
1479b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(CodeItem);
1480b1994897Sopenharmony_ci
1481b1994897Sopenharmony_ciprivate:
1482b1994897Sopenharmony_ci    size_t num_vregs_ {0};
1483b1994897Sopenharmony_ci    size_t num_args_ {0};
1484b1994897Sopenharmony_ci    size_t num_ins_ {0};
1485b1994897Sopenharmony_ci    std::vector<uint8_t> instructions_;
1486b1994897Sopenharmony_ci    std::vector<TryBlock> try_blocks_;
1487b1994897Sopenharmony_ci    std::vector<BaseMethodItem *> methods_;
1488b1994897Sopenharmony_ci};
1489b1994897Sopenharmony_ci
1490b1994897Sopenharmony_ciclass ScalarValueItem;
1491b1994897Sopenharmony_ciclass ArrayValueItem;
1492b1994897Sopenharmony_ci
1493b1994897Sopenharmony_ciclass ValueItem : public IndexedItem {
1494b1994897Sopenharmony_cipublic:
1495b1994897Sopenharmony_ci    enum class Type { INTEGER, LONG, FLOAT, DOUBLE, ID, ARRAY };
1496b1994897Sopenharmony_ci
1497b1994897Sopenharmony_ci    explicit ValueItem(Type type, ItemContainer *container) : IndexedItem(container), type_(type) {}
1498b1994897Sopenharmony_ci
1499b1994897Sopenharmony_ci    ~ValueItem() override = default;
1500b1994897Sopenharmony_ci
1501b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(ValueItem);
1502b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(ValueItem);
1503b1994897Sopenharmony_ci
1504b1994897Sopenharmony_ci    Type GetType() const
1505b1994897Sopenharmony_ci    {
1506b1994897Sopenharmony_ci        return type_;
1507b1994897Sopenharmony_ci    }
1508b1994897Sopenharmony_ci
1509b1994897Sopenharmony_ci    bool IsArray() const
1510b1994897Sopenharmony_ci    {
1511b1994897Sopenharmony_ci        return type_ == Type::ARRAY;
1512b1994897Sopenharmony_ci    }
1513b1994897Sopenharmony_ci
1514b1994897Sopenharmony_ci    bool Is32bit() const
1515b1994897Sopenharmony_ci    {
1516b1994897Sopenharmony_ci        return type_ == Type::INTEGER || type_ == Type::FLOAT || type_ == Type::ID;
1517b1994897Sopenharmony_ci    }
1518b1994897Sopenharmony_ci
1519b1994897Sopenharmony_ci    ItemTypes GetItemType() const override
1520b1994897Sopenharmony_ci    {
1521b1994897Sopenharmony_ci        return ItemTypes::VALUE_ITEM;
1522b1994897Sopenharmony_ci    }
1523b1994897Sopenharmony_ci
1524b1994897Sopenharmony_ci    ScalarValueItem *GetAsScalar();
1525b1994897Sopenharmony_ci
1526b1994897Sopenharmony_ci    ArrayValueItem *GetAsArray();
1527b1994897Sopenharmony_ci
1528b1994897Sopenharmony_ciprivate:
1529b1994897Sopenharmony_ci    Type type_;
1530b1994897Sopenharmony_ci};
1531b1994897Sopenharmony_ci
1532b1994897Sopenharmony_ciclass ScalarValueItem : public ValueItem {
1533b1994897Sopenharmony_cipublic:
1534b1994897Sopenharmony_ci    explicit ScalarValueItem(uint32_t v, ItemContainer *container) : ValueItem(Type::INTEGER, container), value_(v) {}
1535b1994897Sopenharmony_ci
1536b1994897Sopenharmony_ci    explicit ScalarValueItem(uint64_t v, ItemContainer *container) : ValueItem(Type::LONG, container), value_(v) {}
1537b1994897Sopenharmony_ci
1538b1994897Sopenharmony_ci    explicit ScalarValueItem(float v, ItemContainer *container) : ValueItem(Type::FLOAT, container), value_(v) {}
1539b1994897Sopenharmony_ci
1540b1994897Sopenharmony_ci    explicit ScalarValueItem(double v, ItemContainer *container) : ValueItem(Type::DOUBLE, container), value_(v) {}
1541b1994897Sopenharmony_ci
1542b1994897Sopenharmony_ci    explicit ScalarValueItem(BaseItem *v, ItemContainer *container) : ValueItem(Type::ID, container), value_(v) {}
1543b1994897Sopenharmony_ci
1544b1994897Sopenharmony_ci    ~ScalarValueItem() override = default;
1545b1994897Sopenharmony_ci
1546b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(ScalarValueItem);
1547b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(ScalarValueItem);
1548b1994897Sopenharmony_ci
1549b1994897Sopenharmony_ci    template <class T>
1550b1994897Sopenharmony_ci    T GetValue() const
1551b1994897Sopenharmony_ci    {
1552b1994897Sopenharmony_ci        return std::get<T>(value_);
1553b1994897Sopenharmony_ci    }
1554b1994897Sopenharmony_ci
1555b1994897Sopenharmony_ci    File::EntityId GetId() const
1556b1994897Sopenharmony_ci    {
1557b1994897Sopenharmony_ci        return File::EntityId(GetValue<BaseItem *>()->GetOffset());
1558b1994897Sopenharmony_ci    }
1559b1994897Sopenharmony_ci
1560b1994897Sopenharmony_ci    size_t GetULeb128EncodedSize();
1561b1994897Sopenharmony_ci
1562b1994897Sopenharmony_ci    size_t GetSLeb128EncodedSize();
1563b1994897Sopenharmony_ci
1564b1994897Sopenharmony_ci    size_t CalculateSize() const override;
1565b1994897Sopenharmony_ci
1566b1994897Sopenharmony_ci    size_t Alignment() override;
1567b1994897Sopenharmony_ci
1568b1994897Sopenharmony_ci    bool Write(Writer *writer) override;
1569b1994897Sopenharmony_ci
1570b1994897Sopenharmony_ci    bool WriteAsUleb128(Writer *writer);
1571b1994897Sopenharmony_ci
1572b1994897Sopenharmony_ciprivate:
1573b1994897Sopenharmony_ci    std::variant<uint32_t, uint64_t, float, double, BaseItem *> value_;
1574b1994897Sopenharmony_ci};
1575b1994897Sopenharmony_ci
1576b1994897Sopenharmony_ciclass ArrayValueItem : public ValueItem {
1577b1994897Sopenharmony_cipublic:
1578b1994897Sopenharmony_ci    ArrayValueItem(panda_file::Type component_type, std::vector<ScalarValueItem> items, ItemContainer *container)
1579b1994897Sopenharmony_ci        : ValueItem(Type::ARRAY, container), component_type_(component_type), items_(std::move(items))
1580b1994897Sopenharmony_ci    {
1581b1994897Sopenharmony_ci    }
1582b1994897Sopenharmony_ci
1583b1994897Sopenharmony_ci    ~ArrayValueItem() override = default;
1584b1994897Sopenharmony_ci
1585b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(ArrayValueItem);
1586b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(ArrayValueItem);
1587b1994897Sopenharmony_ci
1588b1994897Sopenharmony_ci    size_t CalculateSize() const override;
1589b1994897Sopenharmony_ci
1590b1994897Sopenharmony_ci    void ComputeLayout() override;
1591b1994897Sopenharmony_ci
1592b1994897Sopenharmony_ci    bool Write(Writer *writer) override;
1593b1994897Sopenharmony_ci
1594b1994897Sopenharmony_ciprivate:
1595b1994897Sopenharmony_ci    size_t GetComponentSize() const;
1596b1994897Sopenharmony_ci
1597b1994897Sopenharmony_ci    panda_file::Type component_type_;
1598b1994897Sopenharmony_ci    std::vector<ScalarValueItem> items_;
1599b1994897Sopenharmony_ci};
1600b1994897Sopenharmony_ci
1601b1994897Sopenharmony_ciclass LiteralItem;
1602b1994897Sopenharmony_ciclass LiteralArrayItem;
1603b1994897Sopenharmony_ci
1604b1994897Sopenharmony_ciclass LiteralItem : public BaseItem {
1605b1994897Sopenharmony_cipublic:
1606b1994897Sopenharmony_ci    enum class Type { B1, B2, B4, B8, STRING, METHOD, LITERALARRAY };
1607b1994897Sopenharmony_ci
1608b1994897Sopenharmony_ci    explicit LiteralItem(uint8_t v) : type_(Type::B1), value_(v) {}
1609b1994897Sopenharmony_ci
1610b1994897Sopenharmony_ci    explicit LiteralItem(uint16_t v) : type_(Type::B2), value_(v) {}
1611b1994897Sopenharmony_ci
1612b1994897Sopenharmony_ci    explicit LiteralItem(uint32_t v) : type_(Type::B4), value_(v) {}
1613b1994897Sopenharmony_ci
1614b1994897Sopenharmony_ci    explicit LiteralItem(uint64_t v) : type_(Type::B8), value_(v) {}
1615b1994897Sopenharmony_ci
1616b1994897Sopenharmony_ci    explicit LiteralItem(StringItem *v) : type_(Type::STRING), value_(v) {}
1617b1994897Sopenharmony_ci
1618b1994897Sopenharmony_ci    explicit LiteralItem(MethodItem *v) : type_(Type::METHOD), value_(v) {}
1619b1994897Sopenharmony_ci
1620b1994897Sopenharmony_ci    explicit LiteralItem(LiteralArrayItem *v) : type_(Type::LITERALARRAY), value_(v) {}
1621b1994897Sopenharmony_ci
1622b1994897Sopenharmony_ci    ~LiteralItem() override = default;
1623b1994897Sopenharmony_ci
1624b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(LiteralItem);
1625b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(LiteralItem);
1626b1994897Sopenharmony_ci
1627b1994897Sopenharmony_ci    Type GetType() const
1628b1994897Sopenharmony_ci    {
1629b1994897Sopenharmony_ci        return type_;
1630b1994897Sopenharmony_ci    }
1631b1994897Sopenharmony_ci
1632b1994897Sopenharmony_ci    ItemTypes GetItemType() const override
1633b1994897Sopenharmony_ci    {
1634b1994897Sopenharmony_ci        return ItemTypes::LITERAL_ITEM;
1635b1994897Sopenharmony_ci    }
1636b1994897Sopenharmony_ci
1637b1994897Sopenharmony_ci    template <class T>
1638b1994897Sopenharmony_ci    T GetValue() const
1639b1994897Sopenharmony_ci    {
1640b1994897Sopenharmony_ci        return std::get<T>(value_);
1641b1994897Sopenharmony_ci    }
1642b1994897Sopenharmony_ci
1643b1994897Sopenharmony_ci    size_t CalculateSize() const override;
1644b1994897Sopenharmony_ci
1645b1994897Sopenharmony_ci    size_t Alignment() override;
1646b1994897Sopenharmony_ci
1647b1994897Sopenharmony_ci    File::EntityId GetId() const
1648b1994897Sopenharmony_ci    {
1649b1994897Sopenharmony_ci        return File::EntityId(GetValue<StringItem *>()->GetOffset());
1650b1994897Sopenharmony_ci    }
1651b1994897Sopenharmony_ci
1652b1994897Sopenharmony_ci    File::EntityId GetLiteralArrayFileId() const;
1653b1994897Sopenharmony_ci
1654b1994897Sopenharmony_ci    File::EntityId GetMethodId() const
1655b1994897Sopenharmony_ci    {
1656b1994897Sopenharmony_ci        return File::EntityId(GetValue<MethodItem *>()->GetFileId());
1657b1994897Sopenharmony_ci    }
1658b1994897Sopenharmony_ci
1659b1994897Sopenharmony_ci    bool Write(Writer *writer) override;
1660b1994897Sopenharmony_ci
1661b1994897Sopenharmony_ciprivate:
1662b1994897Sopenharmony_ci    Type type_;
1663b1994897Sopenharmony_ci    std::variant<uint8_t, uint16_t, uint32_t, uint64_t, StringItem *, MethodItem *, LiteralArrayItem *> value_;
1664b1994897Sopenharmony_ci};
1665b1994897Sopenharmony_ci
1666b1994897Sopenharmony_ciclass LiteralArrayItem : public ValueItem {
1667b1994897Sopenharmony_cipublic:
1668b1994897Sopenharmony_ci    explicit LiteralArrayItem(ItemContainer *container) : ValueItem(Type::ARRAY, container) {}
1669b1994897Sopenharmony_ci
1670b1994897Sopenharmony_ci    ~LiteralArrayItem() override = default;
1671b1994897Sopenharmony_ci
1672b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(LiteralArrayItem);
1673b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(LiteralArrayItem);
1674b1994897Sopenharmony_ci
1675b1994897Sopenharmony_ci    void AddItems(const std::vector<LiteralItem> &item);
1676b1994897Sopenharmony_ci
1677b1994897Sopenharmony_ci    size_t CalculateSize() const override;
1678b1994897Sopenharmony_ci
1679b1994897Sopenharmony_ci    void ComputeLayout() override;
1680b1994897Sopenharmony_ci
1681b1994897Sopenharmony_ci    bool Write(Writer *writer) override;
1682b1994897Sopenharmony_ci
1683b1994897Sopenharmony_ci    IndexType GetIndexType() const override
1684b1994897Sopenharmony_ci    {
1685b1994897Sopenharmony_ci        return IndexType::METHOD_STRING_LITERAL;
1686b1994897Sopenharmony_ci    }
1687b1994897Sopenharmony_ci
1688b1994897Sopenharmony_ci    ItemTypes GetItemType() const override
1689b1994897Sopenharmony_ci    {
1690b1994897Sopenharmony_ci        return ItemTypes::LITERAL_ARRAY_ITEM;
1691b1994897Sopenharmony_ci    }
1692b1994897Sopenharmony_ci
1693b1994897Sopenharmony_ciprivate:
1694b1994897Sopenharmony_ci    std::vector<LiteralItem> items_;
1695b1994897Sopenharmony_ci};
1696b1994897Sopenharmony_ci
1697b1994897Sopenharmony_ciclass AnnotationItem : public BaseItem {
1698b1994897Sopenharmony_cipublic:
1699b1994897Sopenharmony_ci    class Elem {
1700b1994897Sopenharmony_ci    public:
1701b1994897Sopenharmony_ci        Elem(StringItem *name, ValueItem *value) : name_(name), value_(value)
1702b1994897Sopenharmony_ci        {
1703b1994897Sopenharmony_ci            value_->SetNeedsEmit(!value_->Is32bit());
1704b1994897Sopenharmony_ci        }
1705b1994897Sopenharmony_ci
1706b1994897Sopenharmony_ci        ~Elem() = default;
1707b1994897Sopenharmony_ci
1708b1994897Sopenharmony_ci        DEFAULT_MOVE_SEMANTIC(Elem);
1709b1994897Sopenharmony_ci        DEFAULT_COPY_SEMANTIC(Elem);
1710b1994897Sopenharmony_ci
1711b1994897Sopenharmony_ci        const StringItem *GetName()
1712b1994897Sopenharmony_ci        {
1713b1994897Sopenharmony_ci            return name_;
1714b1994897Sopenharmony_ci        }
1715b1994897Sopenharmony_ci
1716b1994897Sopenharmony_ci        ValueItem *GetValue()
1717b1994897Sopenharmony_ci        {
1718b1994897Sopenharmony_ci            return value_;
1719b1994897Sopenharmony_ci        }
1720b1994897Sopenharmony_ci
1721b1994897Sopenharmony_ci        void SetValue(ValueItem *item)
1722b1994897Sopenharmony_ci        {
1723b1994897Sopenharmony_ci            value_ = item;
1724b1994897Sopenharmony_ci        }
1725b1994897Sopenharmony_ci
1726b1994897Sopenharmony_ci    private:
1727b1994897Sopenharmony_ci        StringItem *name_;
1728b1994897Sopenharmony_ci        ValueItem *value_;
1729b1994897Sopenharmony_ci    };
1730b1994897Sopenharmony_ci
1731b1994897Sopenharmony_ci    class Tag {
1732b1994897Sopenharmony_ci    public:
1733b1994897Sopenharmony_ci        explicit Tag(char item) : item_(item) {}
1734b1994897Sopenharmony_ci
1735b1994897Sopenharmony_ci        ~Tag() = default;
1736b1994897Sopenharmony_ci
1737b1994897Sopenharmony_ci        DEFAULT_MOVE_SEMANTIC(Tag);
1738b1994897Sopenharmony_ci        DEFAULT_COPY_SEMANTIC(Tag);
1739b1994897Sopenharmony_ci
1740b1994897Sopenharmony_ci        uint8_t GetItem() const
1741b1994897Sopenharmony_ci        {
1742b1994897Sopenharmony_ci            return item_;
1743b1994897Sopenharmony_ci        }
1744b1994897Sopenharmony_ci
1745b1994897Sopenharmony_ci    private:
1746b1994897Sopenharmony_ci        uint8_t item_;
1747b1994897Sopenharmony_ci    };
1748b1994897Sopenharmony_ci
1749b1994897Sopenharmony_ci    AnnotationItem(BaseClassItem *cls, std::vector<Elem> elements, std::vector<Tag> tags)
1750b1994897Sopenharmony_ci        : class_(cls), elements_(std::move(elements)), tags_(std::move(tags))
1751b1994897Sopenharmony_ci    {
1752b1994897Sopenharmony_ci        AddIndexDependency(cls);
1753b1994897Sopenharmony_ci    }
1754b1994897Sopenharmony_ci
1755b1994897Sopenharmony_ci    ~AnnotationItem() override = default;
1756b1994897Sopenharmony_ci
1757b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(AnnotationItem);
1758b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(AnnotationItem);
1759b1994897Sopenharmony_ci
1760b1994897Sopenharmony_ci    size_t CalculateSize() const override;
1761b1994897Sopenharmony_ci
1762b1994897Sopenharmony_ci    bool Write(Writer *writer) override;
1763b1994897Sopenharmony_ci
1764b1994897Sopenharmony_ci    ItemTypes GetItemType() const override
1765b1994897Sopenharmony_ci    {
1766b1994897Sopenharmony_ci        return ItemTypes::ANNOTATION_ITEM;
1767b1994897Sopenharmony_ci    }
1768b1994897Sopenharmony_ci
1769b1994897Sopenharmony_ci    std::vector<Elem> *GetElements()
1770b1994897Sopenharmony_ci    {
1771b1994897Sopenharmony_ci        return &elements_;
1772b1994897Sopenharmony_ci    }
1773b1994897Sopenharmony_ci
1774b1994897Sopenharmony_ci    void SetElements(std::vector<Elem> &&elements)
1775b1994897Sopenharmony_ci    {
1776b1994897Sopenharmony_ci        elements_ = std::move(elements);
1777b1994897Sopenharmony_ci    }
1778b1994897Sopenharmony_ci
1779b1994897Sopenharmony_ci    const std::vector<Tag> &GetTags() const
1780b1994897Sopenharmony_ci    {
1781b1994897Sopenharmony_ci        return tags_;
1782b1994897Sopenharmony_ci    }
1783b1994897Sopenharmony_ci
1784b1994897Sopenharmony_ci    void SetTags(std::vector<Tag> &&tags)
1785b1994897Sopenharmony_ci    {
1786b1994897Sopenharmony_ci        tags_ = std::move(tags);
1787b1994897Sopenharmony_ci    }
1788b1994897Sopenharmony_ci
1789b1994897Sopenharmony_ciprivate:
1790b1994897Sopenharmony_ci    BaseClassItem *class_;
1791b1994897Sopenharmony_ci    std::vector<Elem> elements_;
1792b1994897Sopenharmony_ci    std::vector<Tag> tags_;
1793b1994897Sopenharmony_ci};
1794b1994897Sopenharmony_ci
1795b1994897Sopenharmony_cienum class MethodHandleType : uint8_t {
1796b1994897Sopenharmony_ci    PUT_STATIC = 0x00,
1797b1994897Sopenharmony_ci    GET_STATIC = 0x01,
1798b1994897Sopenharmony_ci    PUT_INSTANCE = 0x02,
1799b1994897Sopenharmony_ci    GET_INSTANCE = 0x03,
1800b1994897Sopenharmony_ci    INVOKE_STATIC = 0x04,
1801b1994897Sopenharmony_ci    INVOKE_INSTANCE = 0x05,
1802b1994897Sopenharmony_ci    INVOKE_CONSTRUCTOR = 0x06,
1803b1994897Sopenharmony_ci    INVOKE_DIRECT = 0x07,
1804b1994897Sopenharmony_ci    INVOKE_INTERFACE = 0x08
1805b1994897Sopenharmony_ci};
1806b1994897Sopenharmony_ci
1807b1994897Sopenharmony_ciclass MethodHandleItem : public BaseItem {
1808b1994897Sopenharmony_cipublic:
1809b1994897Sopenharmony_ci    MethodHandleItem(MethodHandleType type, BaseItem *entity) : type_(type), entity_(entity) {}
1810b1994897Sopenharmony_ci
1811b1994897Sopenharmony_ci    ~MethodHandleItem() override = default;
1812b1994897Sopenharmony_ci
1813b1994897Sopenharmony_ci    DEFAULT_MOVE_SEMANTIC(MethodHandleItem);
1814b1994897Sopenharmony_ci    DEFAULT_COPY_SEMANTIC(MethodHandleItem);
1815b1994897Sopenharmony_ci
1816b1994897Sopenharmony_ci    size_t CalculateSize() const override
1817b1994897Sopenharmony_ci    {
1818b1994897Sopenharmony_ci        return sizeof(uint8_t) + leb128::UnsignedEncodingSize(entity_->GetOffset());
1819b1994897Sopenharmony_ci    }
1820b1994897Sopenharmony_ci
1821b1994897Sopenharmony_ci    bool Write(Writer *writer) override;
1822b1994897Sopenharmony_ci
1823b1994897Sopenharmony_ci    ItemTypes GetItemType() const override
1824b1994897Sopenharmony_ci    {
1825b1994897Sopenharmony_ci        return ItemTypes::METHOD_HANDLE_ITEM;
1826b1994897Sopenharmony_ci    }
1827b1994897Sopenharmony_ci
1828b1994897Sopenharmony_ci    MethodHandleType GetType() const
1829b1994897Sopenharmony_ci    {
1830b1994897Sopenharmony_ci        return type_;
1831b1994897Sopenharmony_ci    }
1832b1994897Sopenharmony_ci
1833b1994897Sopenharmony_ciprivate:
1834b1994897Sopenharmony_ci    MethodHandleType type_;
1835b1994897Sopenharmony_ci    BaseItem *entity_;
1836b1994897Sopenharmony_ci};
1837b1994897Sopenharmony_ci
1838b1994897Sopenharmony_cienum class ArgumentType : uint8_t {
1839b1994897Sopenharmony_ci    INTEGER = 0x00,
1840b1994897Sopenharmony_ci    LONG = 0x01,
1841b1994897Sopenharmony_ci    FLOAT = 0x02,
1842b1994897Sopenharmony_ci    DOUBLE = 0x03,
1843b1994897Sopenharmony_ci    STRING = 0x04,
1844b1994897Sopenharmony_ci    CLASS = 0x05,
1845b1994897Sopenharmony_ci    METHOD_HANDLE = 0x06,
1846b1994897Sopenharmony_ci    METHOD_TYPE = 0x07
1847b1994897Sopenharmony_ci};
1848b1994897Sopenharmony_ci
1849b1994897Sopenharmony_ci}  // namespace panda::panda_file
1850b1994897Sopenharmony_ci
1851b1994897Sopenharmony_ci#endif  // LIBPANDAFILE_FILE_ITEMS_H
1852