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#include <cstdint>
17b1994897Sopenharmony_ci
18b1994897Sopenharmony_ci#include "libpandafile/bytecode_instruction-inl.h"
19b1994897Sopenharmony_ci#include "libpandafile/line_number_program.h"
20b1994897Sopenharmony_ci#include "libpandafile/literal_data_accessor-inl.h"
21b1994897Sopenharmony_ci#include "libpandafile/class_data_accessor-inl.h"
22b1994897Sopenharmony_ci#include "libpandafile/proto_data_accessor-inl.h"
23b1994897Sopenharmony_ci#include "libpandafile/code_data_accessor-inl.h"
24b1994897Sopenharmony_ci#include "libpandafile/debug_data_accessor-inl.h"
25b1994897Sopenharmony_ci#include "libpandafile/field_data_accessor-inl.h"
26b1994897Sopenharmony_ci#include "libpandafile/method_data_accessor-inl.h"
27b1994897Sopenharmony_ci
28b1994897Sopenharmony_ci#include "file.h"
29b1994897Sopenharmony_ci
30b1994897Sopenharmony_ci#include "libpandabase/utils/utf.h"
31b1994897Sopenharmony_ci
32b1994897Sopenharmony_ci#include "libpandafile/file_reader.h"
33b1994897Sopenharmony_ci
34b1994897Sopenharmony_cinamespace panda::panda_file {
35b1994897Sopenharmony_ci
36b1994897Sopenharmony_cibool FileReader::ReadContainer()
37b1994897Sopenharmony_ci{
38b1994897Sopenharmony_ci    if (!ReadClasses()) {
39b1994897Sopenharmony_ci        return false;
40b1994897Sopenharmony_ci    }
41b1994897Sopenharmony_ci    if (!ReadLiteralArrayItems()) {
42b1994897Sopenharmony_ci        return false;
43b1994897Sopenharmony_ci    }
44b1994897Sopenharmony_ci    if (!ReadIndexHeaders()) {
45b1994897Sopenharmony_ci        return false;
46b1994897Sopenharmony_ci    }
47b1994897Sopenharmony_ci
48b1994897Sopenharmony_ci    ComputeLayoutAndUpdateIndices();
49b1994897Sopenharmony_ci
50b1994897Sopenharmony_ci    return true;
51b1994897Sopenharmony_ci}
52b1994897Sopenharmony_ci
53b1994897Sopenharmony_ci/* static */
54b1994897Sopenharmony_cibool FileReader::CreateLiteralArrayItem(const LiteralDataAccessor::LiteralValue &lit_value, const LiteralTag &tag,
55b1994897Sopenharmony_ci                                        File::EntityId array_id)
56b1994897Sopenharmony_ci{
57b1994897Sopenharmony_ci    auto it = items_done_.find(array_id);
58b1994897Sopenharmony_ci    if (it != items_done_.end()) {
59b1994897Sopenharmony_ci        return true;
60b1994897Sopenharmony_ci    }
61b1994897Sopenharmony_ci
62b1994897Sopenharmony_ci    LiteralArrayItem *item = container_.GetOrCreateLiteralArrayItem(std::to_string(array_id.GetOffset()));
63b1994897Sopenharmony_ci    items_done_.insert({array_id, static_cast<BaseItem *>(item)});
64b1994897Sopenharmony_ci
65b1994897Sopenharmony_ci    File::EntityId id(std::get<uint32_t>(lit_value));
66b1994897Sopenharmony_ci    auto sp = file_->GetSpanFromId(id);
67b1994897Sopenharmony_ci
68b1994897Sopenharmony_ci    std::vector<panda_file::LiteralItem> literal_array;
69b1994897Sopenharmony_ci    literal_array.emplace_back(static_cast<uint8_t>(tag));
70b1994897Sopenharmony_ci    switch (tag) {
71b1994897Sopenharmony_ci        case panda_file::LiteralTag::BOOL: {
72b1994897Sopenharmony_ci            auto v = helpers::Read<sizeof(bool)>(&sp);
73b1994897Sopenharmony_ci            literal_array.emplace_back(static_cast<uint8_t>(v));
74b1994897Sopenharmony_ci            break;
75b1994897Sopenharmony_ci        }
76b1994897Sopenharmony_ci        case panda_file::LiteralTag::TAGVALUE:
77b1994897Sopenharmony_ci        case panda_file::LiteralTag::ACCESSOR:
78b1994897Sopenharmony_ci        case panda_file::LiteralTag::NULLVALUE: {
79b1994897Sopenharmony_ci            auto v = helpers::Read<sizeof(uint8_t)>(&sp);
80b1994897Sopenharmony_ci            literal_array.emplace_back(v);
81b1994897Sopenharmony_ci            break;
82b1994897Sopenharmony_ci        }
83b1994897Sopenharmony_ci        case panda_file::LiteralTag::ARRAY_U1:
84b1994897Sopenharmony_ci        case panda_file::LiteralTag::ARRAY_I8:
85b1994897Sopenharmony_ci        case panda_file::LiteralTag::ARRAY_U8: {
86b1994897Sopenharmony_ci            auto len = helpers::Read<sizeof(uint32_t)>(&sp);
87b1994897Sopenharmony_ci            literal_array.emplace_back(len);
88b1994897Sopenharmony_ci            for (size_t i = 0; i < len; i++) {
89b1994897Sopenharmony_ci                auto v = helpers::Read<sizeof(uint8_t)>(&sp);
90b1994897Sopenharmony_ci                literal_array.emplace_back(v);
91b1994897Sopenharmony_ci            }
92b1994897Sopenharmony_ci            break;
93b1994897Sopenharmony_ci        }
94b1994897Sopenharmony_ci        case panda_file::LiteralTag::ARRAY_I16:
95b1994897Sopenharmony_ci        case panda_file::LiteralTag::ARRAY_U16: {
96b1994897Sopenharmony_ci            auto len = helpers::Read<sizeof(uint32_t)>(&sp);
97b1994897Sopenharmony_ci            literal_array.emplace_back(len);
98b1994897Sopenharmony_ci            for (size_t i = 0; i < len; i++) {
99b1994897Sopenharmony_ci                auto v = helpers::Read<sizeof(uint16_t)>(&sp);
100b1994897Sopenharmony_ci                literal_array.emplace_back(v);
101b1994897Sopenharmony_ci            }
102b1994897Sopenharmony_ci            break;
103b1994897Sopenharmony_ci        }
104b1994897Sopenharmony_ci        case panda_file::LiteralTag::INTEGER: {
105b1994897Sopenharmony_ci            auto v = helpers::Read<sizeof(uint32_t)>(&sp);
106b1994897Sopenharmony_ci            literal_array.emplace_back(v);
107b1994897Sopenharmony_ci            break;
108b1994897Sopenharmony_ci        }
109b1994897Sopenharmony_ci        case panda_file::LiteralTag::ARRAY_I32:
110b1994897Sopenharmony_ci        case panda_file::LiteralTag::ARRAY_U32:
111b1994897Sopenharmony_ci        case panda_file::LiteralTag::ARRAY_F32: {
112b1994897Sopenharmony_ci            auto len = helpers::Read<sizeof(uint32_t)>(&sp);
113b1994897Sopenharmony_ci            literal_array.emplace_back(len);
114b1994897Sopenharmony_ci            for (size_t i = 0; i < len; i++) {
115b1994897Sopenharmony_ci                auto v = helpers::Read<sizeof(uint32_t)>(&sp);
116b1994897Sopenharmony_ci                literal_array.emplace_back(v);
117b1994897Sopenharmony_ci            }
118b1994897Sopenharmony_ci            break;
119b1994897Sopenharmony_ci        }
120b1994897Sopenharmony_ci        case panda_file::LiteralTag::ARRAY_I64:
121b1994897Sopenharmony_ci        case panda_file::LiteralTag::ARRAY_U64:
122b1994897Sopenharmony_ci        case panda_file::LiteralTag::ARRAY_F64: {
123b1994897Sopenharmony_ci            auto len = helpers::Read<sizeof(uint32_t)>(&sp);
124b1994897Sopenharmony_ci            literal_array.emplace_back(len);
125b1994897Sopenharmony_ci            for (size_t i = 0; i < len; i++) {
126b1994897Sopenharmony_ci                auto v = helpers::Read<sizeof(uint64_t)>(&sp);
127b1994897Sopenharmony_ci                literal_array.emplace_back(v);
128b1994897Sopenharmony_ci            }
129b1994897Sopenharmony_ci            break;
130b1994897Sopenharmony_ci        }
131b1994897Sopenharmony_ci        case panda_file::LiteralTag::FLOAT: {
132b1994897Sopenharmony_ci            auto v = helpers::Read<sizeof(uint32_t)>(&sp);
133b1994897Sopenharmony_ci            literal_array.emplace_back(v);
134b1994897Sopenharmony_ci            break;
135b1994897Sopenharmony_ci        }
136b1994897Sopenharmony_ci        case panda_file::LiteralTag::DOUBLE: {
137b1994897Sopenharmony_ci            auto v = panda_file::helpers::Read<sizeof(uint64_t)>(&sp);
138b1994897Sopenharmony_ci            literal_array.emplace_back(v);
139b1994897Sopenharmony_ci            break;
140b1994897Sopenharmony_ci        }
141b1994897Sopenharmony_ci        case panda_file::LiteralTag::STRING: {
142b1994897Sopenharmony_ci            File::EntityId str_id(helpers::Read<sizeof(uint32_t)>(&sp));
143b1994897Sopenharmony_ci            auto data = file_->GetStringData(str_id);
144b1994897Sopenharmony_ci            std::string item_str(utf::Mutf8AsCString(data.data));
145b1994897Sopenharmony_ci            auto *string_item = container_.GetOrCreateStringItem(item_str);
146b1994897Sopenharmony_ci            literal_array.emplace_back(string_item);
147b1994897Sopenharmony_ci            break;
148b1994897Sopenharmony_ci        }
149b1994897Sopenharmony_ci        case panda_file::LiteralTag::ARRAY_STRING: {
150b1994897Sopenharmony_ci            auto len = helpers::Read<sizeof(uint32_t)>(&sp);
151b1994897Sopenharmony_ci            literal_array.emplace_back(len);
152b1994897Sopenharmony_ci            for (size_t i = 0; i < len; i++) {
153b1994897Sopenharmony_ci                File::EntityId str_id(helpers::Read<sizeof(uint32_t)>(&sp));
154b1994897Sopenharmony_ci                auto data = file_->GetStringData(str_id);
155b1994897Sopenharmony_ci                std::string item_str(utf::Mutf8AsCString(data.data));
156b1994897Sopenharmony_ci                auto *string_item = container_.GetOrCreateStringItem(item_str);
157b1994897Sopenharmony_ci                literal_array.emplace_back(string_item);
158b1994897Sopenharmony_ci            }
159b1994897Sopenharmony_ci            break;
160b1994897Sopenharmony_ci        }
161b1994897Sopenharmony_ci        case panda_file::LiteralTag::METHOD:
162b1994897Sopenharmony_ci        case panda_file::LiteralTag::GETTER:
163b1994897Sopenharmony_ci        case panda_file::LiteralTag::SETTER:
164b1994897Sopenharmony_ci        case panda_file::LiteralTag::GENERATORMETHOD:
165b1994897Sopenharmony_ci        case panda_file::LiteralTag::ASYNCGENERATORMETHOD: {
166b1994897Sopenharmony_ci            File::EntityId method_id(helpers::Read<sizeof(uint32_t)>(&sp));
167b1994897Sopenharmony_ci            MethodDataAccessor method_acc(*file_, method_id);
168b1994897Sopenharmony_ci            File::EntityId class_id(method_acc.GetClassId());
169b1994897Sopenharmony_ci            auto *class_item = CreateClassItem(class_id);
170b1994897Sopenharmony_ci            literal_array.emplace_back(CreateMethodItem(class_item, method_id));
171b1994897Sopenharmony_ci            break;
172b1994897Sopenharmony_ci        }
173b1994897Sopenharmony_ci        default:
174b1994897Sopenharmony_ci            UNREACHABLE();
175b1994897Sopenharmony_ci    }
176b1994897Sopenharmony_ci
177b1994897Sopenharmony_ci    item->AddItems(literal_array);
178b1994897Sopenharmony_ci
179b1994897Sopenharmony_ci    return true;
180b1994897Sopenharmony_ci}
181b1994897Sopenharmony_ci
182b1994897Sopenharmony_ci// NOLINTNEXTLINE(readability-function-size)
183b1994897Sopenharmony_ciAnnotationItem *FileReader::CreateAnnotationItem(File::EntityId ann_id)
184b1994897Sopenharmony_ci{
185b1994897Sopenharmony_ci    auto it = items_done_.find(ann_id);
186b1994897Sopenharmony_ci    if (it != items_done_.end()) {
187b1994897Sopenharmony_ci        return static_cast<AnnotationItem *>(it->second);
188b1994897Sopenharmony_ci    }
189b1994897Sopenharmony_ci
190b1994897Sopenharmony_ci    AnnotationDataAccessor ann_acc(*file_, ann_id);
191b1994897Sopenharmony_ci    File::EntityId ann_class_id {ann_acc.GetClassId()};
192b1994897Sopenharmony_ci    AnnotationItem *ann_item = nullptr;
193b1994897Sopenharmony_ci
194b1994897Sopenharmony_ci    if (!file_->IsExternal(ann_class_id)) {
195b1994897Sopenharmony_ci        auto *ann_class_item = CreateClassItem(ann_class_id);
196b1994897Sopenharmony_ci        ann_item = container_.CreateItem<AnnotationItem>(ann_class_item, std::vector<AnnotationItem::Elem>(),
197b1994897Sopenharmony_ci                                                         std::vector<AnnotationItem::Tag>());
198b1994897Sopenharmony_ci    } else {
199b1994897Sopenharmony_ci        auto *ann_class_item = CreateForeignClassItem(ann_class_id);
200b1994897Sopenharmony_ci        ann_item = container_.CreateItem<AnnotationItem>(ann_class_item, std::vector<AnnotationItem::Elem>(),
201b1994897Sopenharmony_ci                                                         std::vector<AnnotationItem::Tag>());
202b1994897Sopenharmony_ci    }
203b1994897Sopenharmony_ci
204b1994897Sopenharmony_ci    ASSERT(ann_item != nullptr);
205b1994897Sopenharmony_ci
206b1994897Sopenharmony_ci    items_done_.insert({ann_id, static_cast<BaseItem *>(ann_item)});
207b1994897Sopenharmony_ci
208b1994897Sopenharmony_ci    std::vector<AnnotationItem::Elem> item_elements;
209b1994897Sopenharmony_ci    std::vector<AnnotationItem::Tag> tag_elements;
210b1994897Sopenharmony_ci
211b1994897Sopenharmony_ci    for (size_t i = 0; i < ann_acc.GetCount(); i++) {
212b1994897Sopenharmony_ci        AnnotationDataAccessor::Tag ann_tag = ann_acc.GetTag(i);
213b1994897Sopenharmony_ci        AnnotationDataAccessor::Elem ann_elem = ann_acc.GetElement(i);
214b1994897Sopenharmony_ci        ValueItem *elem_value_item = nullptr;
215b1994897Sopenharmony_ci        switch (ann_tag.GetItem()) {
216b1994897Sopenharmony_ci            case '1':
217b1994897Sopenharmony_ci            case '2':
218b1994897Sopenharmony_ci            case '3': {
219b1994897Sopenharmony_ci                auto scalar = ann_elem.GetScalarValue();
220b1994897Sopenharmony_ci                elem_value_item = container_.GetOrCreateIntegerValueItem(scalar.Get<uint8_t>());
221b1994897Sopenharmony_ci                break;
222b1994897Sopenharmony_ci            }
223b1994897Sopenharmony_ci            case '4':
224b1994897Sopenharmony_ci            case '5': {
225b1994897Sopenharmony_ci                auto scalar = ann_elem.GetScalarValue();
226b1994897Sopenharmony_ci                elem_value_item = container_.GetOrCreateIntegerValueItem(scalar.Get<uint16_t>());
227b1994897Sopenharmony_ci                break;
228b1994897Sopenharmony_ci            }
229b1994897Sopenharmony_ci            case '6':
230b1994897Sopenharmony_ci            case '7': {
231b1994897Sopenharmony_ci                auto scalar = ann_elem.GetScalarValue();
232b1994897Sopenharmony_ci                elem_value_item = container_.GetOrCreateIntegerValueItem(scalar.Get<uint32_t>());
233b1994897Sopenharmony_ci                break;
234b1994897Sopenharmony_ci            }
235b1994897Sopenharmony_ci            case '8':
236b1994897Sopenharmony_ci            case '9': {
237b1994897Sopenharmony_ci                auto scalar = ann_elem.GetScalarValue();
238b1994897Sopenharmony_ci                elem_value_item = container_.GetOrCreateLongValueItem(scalar.Get<uint64_t>());
239b1994897Sopenharmony_ci                break;
240b1994897Sopenharmony_ci            }
241b1994897Sopenharmony_ci            case 'A': {
242b1994897Sopenharmony_ci                auto scalar = ann_elem.GetScalarValue();
243b1994897Sopenharmony_ci                elem_value_item = container_.GetOrCreateFloatValueItem(scalar.Get<float>());
244b1994897Sopenharmony_ci                break;
245b1994897Sopenharmony_ci            }
246b1994897Sopenharmony_ci            case 'B': {
247b1994897Sopenharmony_ci                auto scalar = ann_elem.GetScalarValue();
248b1994897Sopenharmony_ci                elem_value_item = container_.GetOrCreateDoubleValueItem(scalar.Get<double>());
249b1994897Sopenharmony_ci                break;
250b1994897Sopenharmony_ci            }
251b1994897Sopenharmony_ci            case 'C': {
252b1994897Sopenharmony_ci                auto scalar = ann_elem.GetScalarValue();
253b1994897Sopenharmony_ci                const File::EntityId str_id(scalar.Get<uint32_t>());
254b1994897Sopenharmony_ci                auto data = file_->GetStringData(str_id);
255b1994897Sopenharmony_ci                std::string item_str(utf::Mutf8AsCString(data.data));
256b1994897Sopenharmony_ci                auto *str_item = container_.GetOrCreateStringItem(item_str);
257b1994897Sopenharmony_ci                elem_value_item = container_.GetOrCreateIdValueItem(str_item);
258b1994897Sopenharmony_ci                break;
259b1994897Sopenharmony_ci            }
260b1994897Sopenharmony_ci            case 'D': {
261b1994897Sopenharmony_ci                auto scalar = ann_elem.GetScalarValue();
262b1994897Sopenharmony_ci                const File::EntityId class_id {scalar.Get<uint32_t>()};
263b1994897Sopenharmony_ci                elem_value_item = container_.GetOrCreateIdValueItem(CreateGenericClassItem(class_id));
264b1994897Sopenharmony_ci                break;
265b1994897Sopenharmony_ci            }
266b1994897Sopenharmony_ci            case 'E': {
267b1994897Sopenharmony_ci                auto scalar = ann_elem.GetScalarValue();
268b1994897Sopenharmony_ci                const File::EntityId method_id {scalar.Get<uint32_t>()};
269b1994897Sopenharmony_ci                MethodDataAccessor method_acc(*file_, method_id);
270b1994897Sopenharmony_ci                auto *cls_item = CreateGenericClassItem(method_acc.GetClassId());
271b1994897Sopenharmony_ci                elem_value_item = container_.GetOrCreateIdValueItem(CreateGenericMethodItem(cls_item, method_id));
272b1994897Sopenharmony_ci                break;
273b1994897Sopenharmony_ci            }
274b1994897Sopenharmony_ci            case 'F': {
275b1994897Sopenharmony_ci                auto scalar = ann_elem.GetScalarValue();
276b1994897Sopenharmony_ci                const File::EntityId field_id {scalar.Get<uint32_t>()};
277b1994897Sopenharmony_ci                FieldDataAccessor field_acc(*file_, field_id);
278b1994897Sopenharmony_ci                auto *cls_item = CreateGenericClassItem(field_acc.GetClassId());
279b1994897Sopenharmony_ci                elem_value_item = container_.GetOrCreateIdValueItem(CreateGenericFieldItem(cls_item, field_id));
280b1994897Sopenharmony_ci                break;
281b1994897Sopenharmony_ci            }
282b1994897Sopenharmony_ci            case 'G': {
283b1994897Sopenharmony_ci                auto scalar = ann_elem.GetScalarValue();
284b1994897Sopenharmony_ci                const File::EntityId ann_item_id {scalar.Get<uint32_t>()};
285b1994897Sopenharmony_ci                elem_value_item = container_.GetOrCreateIdValueItem(CreateAnnotationItem(ann_item_id));
286b1994897Sopenharmony_ci                break;
287b1994897Sopenharmony_ci            }
288b1994897Sopenharmony_ci            case 'J': {
289b1994897Sopenharmony_ci                LOG(FATAL, PANDAFILE) << "MethodHandle is not supported so far";
290b1994897Sopenharmony_ci                break;
291b1994897Sopenharmony_ci            }
292b1994897Sopenharmony_ci            case '*': {
293b1994897Sopenharmony_ci                elem_value_item = container_.GetOrCreateIntegerValueItem(0);
294b1994897Sopenharmony_ci                break;
295b1994897Sopenharmony_ci            }
296b1994897Sopenharmony_ci            case 'K': {
297b1994897Sopenharmony_ci                auto array = ann_elem.GetArrayValue();
298b1994897Sopenharmony_ci                std::vector<ScalarValueItem> items;
299b1994897Sopenharmony_ci                for (size_t j = 0; j < array.GetCount(); j++) {
300b1994897Sopenharmony_ci                    ScalarValueItem scalar(static_cast<uint32_t>(array.Get<uint8_t>(j)));
301b1994897Sopenharmony_ci                    items.emplace_back(std::move(scalar));
302b1994897Sopenharmony_ci                }
303b1994897Sopenharmony_ci                elem_value_item = static_cast<ValueItem *>(
304b1994897Sopenharmony_ci                    container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::U1), std::move(items)));
305b1994897Sopenharmony_ci                break;
306b1994897Sopenharmony_ci            }
307b1994897Sopenharmony_ci            case 'L': {
308b1994897Sopenharmony_ci                auto array = ann_elem.GetArrayValue();
309b1994897Sopenharmony_ci                std::vector<ScalarValueItem> items;
310b1994897Sopenharmony_ci                for (size_t j = 0; j < array.GetCount(); j++) {
311b1994897Sopenharmony_ci                    ScalarValueItem scalar(static_cast<uint32_t>(array.Get<uint8_t>(j)));
312b1994897Sopenharmony_ci                    items.emplace_back(std::move(scalar));
313b1994897Sopenharmony_ci                }
314b1994897Sopenharmony_ci                elem_value_item = static_cast<ValueItem *>(
315b1994897Sopenharmony_ci                    container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::I8), std::move(items)));
316b1994897Sopenharmony_ci                break;
317b1994897Sopenharmony_ci            }
318b1994897Sopenharmony_ci            case 'M': {
319b1994897Sopenharmony_ci                auto array = ann_elem.GetArrayValue();
320b1994897Sopenharmony_ci                std::vector<ScalarValueItem> items;
321b1994897Sopenharmony_ci                for (size_t j = 0; j < array.GetCount(); j++) {
322b1994897Sopenharmony_ci                    ScalarValueItem scalar(static_cast<uint32_t>(array.Get<uint8_t>(j)));
323b1994897Sopenharmony_ci                    items.emplace_back(std::move(scalar));
324b1994897Sopenharmony_ci                }
325b1994897Sopenharmony_ci                elem_value_item = static_cast<ValueItem *>(
326b1994897Sopenharmony_ci                    container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::U8), std::move(items)));
327b1994897Sopenharmony_ci                break;
328b1994897Sopenharmony_ci            }
329b1994897Sopenharmony_ci            case 'N': {
330b1994897Sopenharmony_ci                auto array = ann_elem.GetArrayValue();
331b1994897Sopenharmony_ci                std::vector<ScalarValueItem> items;
332b1994897Sopenharmony_ci                for (size_t j = 0; j < array.GetCount(); j++) {
333b1994897Sopenharmony_ci                    ScalarValueItem scalar(static_cast<uint32_t>(array.Get<uint16_t>(j)));
334b1994897Sopenharmony_ci                    items.emplace_back(std::move(scalar));
335b1994897Sopenharmony_ci                }
336b1994897Sopenharmony_ci                elem_value_item = static_cast<ValueItem *>(
337b1994897Sopenharmony_ci                    container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::I16), std::move(items)));
338b1994897Sopenharmony_ci                break;
339b1994897Sopenharmony_ci            }
340b1994897Sopenharmony_ci            case 'O': {
341b1994897Sopenharmony_ci                auto array = ann_elem.GetArrayValue();
342b1994897Sopenharmony_ci                std::vector<ScalarValueItem> items;
343b1994897Sopenharmony_ci                for (size_t j = 0; j < array.GetCount(); j++) {
344b1994897Sopenharmony_ci                    ScalarValueItem scalar(static_cast<uint32_t>(array.Get<uint16_t>(j)));
345b1994897Sopenharmony_ci                    items.emplace_back(std::move(scalar));
346b1994897Sopenharmony_ci                }
347b1994897Sopenharmony_ci                elem_value_item = static_cast<ValueItem *>(
348b1994897Sopenharmony_ci                    container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::U16), std::move(items)));
349b1994897Sopenharmony_ci                break;
350b1994897Sopenharmony_ci            }
351b1994897Sopenharmony_ci            case 'P': {
352b1994897Sopenharmony_ci                auto array = ann_elem.GetArrayValue();
353b1994897Sopenharmony_ci                std::vector<ScalarValueItem> items;
354b1994897Sopenharmony_ci                for (size_t j = 0; j < array.GetCount(); j++) {
355b1994897Sopenharmony_ci                    ScalarValueItem scalar(array.Get<uint32_t>(j));
356b1994897Sopenharmony_ci                    items.emplace_back(std::move(scalar));
357b1994897Sopenharmony_ci                }
358b1994897Sopenharmony_ci                elem_value_item = static_cast<ValueItem *>(
359b1994897Sopenharmony_ci                    container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::I32), std::move(items)));
360b1994897Sopenharmony_ci                break;
361b1994897Sopenharmony_ci            }
362b1994897Sopenharmony_ci            case 'Q': {
363b1994897Sopenharmony_ci                auto array = ann_elem.GetArrayValue();
364b1994897Sopenharmony_ci                std::vector<ScalarValueItem> items;
365b1994897Sopenharmony_ci                for (size_t j = 0; j < array.GetCount(); j++) {
366b1994897Sopenharmony_ci                    ScalarValueItem scalar(array.Get<uint32_t>(j));
367b1994897Sopenharmony_ci                    items.emplace_back(std::move(scalar));
368b1994897Sopenharmony_ci                }
369b1994897Sopenharmony_ci                elem_value_item = static_cast<ValueItem *>(
370b1994897Sopenharmony_ci                    container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::U32), std::move(items)));
371b1994897Sopenharmony_ci                break;
372b1994897Sopenharmony_ci            }
373b1994897Sopenharmony_ci            case 'R': {
374b1994897Sopenharmony_ci                auto array = ann_elem.GetArrayValue();
375b1994897Sopenharmony_ci                std::vector<ScalarValueItem> items;
376b1994897Sopenharmony_ci                for (size_t j = 0; j < array.GetCount(); j++) {
377b1994897Sopenharmony_ci                    ScalarValueItem scalar(array.Get<uint64_t>(j));
378b1994897Sopenharmony_ci                    items.emplace_back(std::move(scalar));
379b1994897Sopenharmony_ci                }
380b1994897Sopenharmony_ci                elem_value_item = static_cast<ValueItem *>(
381b1994897Sopenharmony_ci                    container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::I64), std::move(items)));
382b1994897Sopenharmony_ci                break;
383b1994897Sopenharmony_ci            }
384b1994897Sopenharmony_ci            case 'S': {
385b1994897Sopenharmony_ci                auto array = ann_elem.GetArrayValue();
386b1994897Sopenharmony_ci                std::vector<ScalarValueItem> items;
387b1994897Sopenharmony_ci                for (size_t j = 0; j < array.GetCount(); j++) {
388b1994897Sopenharmony_ci                    ScalarValueItem scalar(array.Get<uint64_t>(j));
389b1994897Sopenharmony_ci                    items.emplace_back(std::move(scalar));
390b1994897Sopenharmony_ci                }
391b1994897Sopenharmony_ci                elem_value_item = static_cast<ValueItem *>(
392b1994897Sopenharmony_ci                    container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::U64), std::move(items)));
393b1994897Sopenharmony_ci                break;
394b1994897Sopenharmony_ci            }
395b1994897Sopenharmony_ci            case 'T': {
396b1994897Sopenharmony_ci                auto array = ann_elem.GetArrayValue();
397b1994897Sopenharmony_ci                std::vector<ScalarValueItem> items;
398b1994897Sopenharmony_ci                for (size_t j = 0; j < array.GetCount(); j++) {
399b1994897Sopenharmony_ci                    ScalarValueItem scalar(array.Get<float>(j));
400b1994897Sopenharmony_ci                    items.emplace_back(std::move(scalar));
401b1994897Sopenharmony_ci                }
402b1994897Sopenharmony_ci                elem_value_item = static_cast<ValueItem *>(
403b1994897Sopenharmony_ci                    container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::F32), std::move(items)));
404b1994897Sopenharmony_ci                break;
405b1994897Sopenharmony_ci            }
406b1994897Sopenharmony_ci            case 'U': {
407b1994897Sopenharmony_ci                auto array = ann_elem.GetArrayValue();
408b1994897Sopenharmony_ci                std::vector<ScalarValueItem> items;
409b1994897Sopenharmony_ci                for (size_t j = 0; j < array.GetCount(); j++) {
410b1994897Sopenharmony_ci                    ScalarValueItem scalar(array.Get<double>(j));
411b1994897Sopenharmony_ci                    items.emplace_back(std::move(scalar));
412b1994897Sopenharmony_ci                }
413b1994897Sopenharmony_ci                elem_value_item = static_cast<ValueItem *>(
414b1994897Sopenharmony_ci                    container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::F64), std::move(items)));
415b1994897Sopenharmony_ci                break;
416b1994897Sopenharmony_ci            }
417b1994897Sopenharmony_ci            case 'V': {
418b1994897Sopenharmony_ci                auto array = ann_elem.GetArrayValue();
419b1994897Sopenharmony_ci                std::vector<ScalarValueItem> items;
420b1994897Sopenharmony_ci                for (size_t j = 0; j < array.GetCount(); j++) {
421b1994897Sopenharmony_ci                    const File::EntityId str_id(array.Get<uint32_t>(j));
422b1994897Sopenharmony_ci                    auto data = file_->GetStringData(str_id);
423b1994897Sopenharmony_ci                    std::string item_str(utf::Mutf8AsCString(data.data));
424b1994897Sopenharmony_ci                    items.emplace_back(ScalarValueItem(container_.GetOrCreateStringItem(item_str)));
425b1994897Sopenharmony_ci                }
426b1994897Sopenharmony_ci                elem_value_item = static_cast<ValueItem *>(
427b1994897Sopenharmony_ci                    container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::REFERENCE), std::move(items)));
428b1994897Sopenharmony_ci                break;
429b1994897Sopenharmony_ci            }
430b1994897Sopenharmony_ci            case 'W': {
431b1994897Sopenharmony_ci                auto array = ann_elem.GetArrayValue();
432b1994897Sopenharmony_ci                std::vector<ScalarValueItem> items;
433b1994897Sopenharmony_ci                for (size_t j = 0; j < array.GetCount(); j++) {
434b1994897Sopenharmony_ci                    const File::EntityId class_id {array.Get<uint32_t>(j)};
435b1994897Sopenharmony_ci                    BaseClassItem *cls_item = nullptr;
436b1994897Sopenharmony_ci                    if (file_->IsExternal(class_id)) {
437b1994897Sopenharmony_ci                        cls_item = CreateForeignClassItem(class_id);
438b1994897Sopenharmony_ci                    } else {
439b1994897Sopenharmony_ci                        cls_item = CreateClassItem(class_id);
440b1994897Sopenharmony_ci                    }
441b1994897Sopenharmony_ci                    ASSERT(cls_item != nullptr);
442b1994897Sopenharmony_ci                    items.emplace_back(ScalarValueItem(cls_item));
443b1994897Sopenharmony_ci                }
444b1994897Sopenharmony_ci                elem_value_item = static_cast<ValueItem *>(
445b1994897Sopenharmony_ci                    container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::REFERENCE), std::move(items)));
446b1994897Sopenharmony_ci                break;
447b1994897Sopenharmony_ci            }
448b1994897Sopenharmony_ci            case 'X': {
449b1994897Sopenharmony_ci                auto array = ann_elem.GetArrayValue();
450b1994897Sopenharmony_ci                std::vector<ScalarValueItem> items;
451b1994897Sopenharmony_ci                for (size_t j = 0; j < array.GetCount(); j++) {
452b1994897Sopenharmony_ci                    const File::EntityId method_id {array.Get<uint32_t>(j)};
453b1994897Sopenharmony_ci                    MethodDataAccessor method_acc(*file_, method_id);
454b1994897Sopenharmony_ci                    auto *cls_item = CreateGenericClassItem(method_acc.GetClassId());
455b1994897Sopenharmony_ci                    items.emplace_back(ScalarValueItem(CreateGenericMethodItem(cls_item, method_id)));
456b1994897Sopenharmony_ci                }
457b1994897Sopenharmony_ci                elem_value_item = static_cast<ValueItem *>(
458b1994897Sopenharmony_ci                    container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::REFERENCE), std::move(items)));
459b1994897Sopenharmony_ci                break;
460b1994897Sopenharmony_ci            }
461b1994897Sopenharmony_ci            case 'Y': {
462b1994897Sopenharmony_ci                auto array = ann_elem.GetArrayValue();
463b1994897Sopenharmony_ci                std::vector<ScalarValueItem> items;
464b1994897Sopenharmony_ci                for (size_t j = 0; j < array.GetCount(); j++) {
465b1994897Sopenharmony_ci                    const File::EntityId field_id {array.Get<uint32_t>(j)};
466b1994897Sopenharmony_ci                    FieldDataAccessor field_acc(*file_, field_id);
467b1994897Sopenharmony_ci                    auto *cls_item = CreateGenericClassItem(field_acc.GetClassId());
468b1994897Sopenharmony_ci                    items.emplace_back(ScalarValueItem(CreateGenericFieldItem(cls_item, field_id)));
469b1994897Sopenharmony_ci                }
470b1994897Sopenharmony_ci                elem_value_item = static_cast<ValueItem *>(
471b1994897Sopenharmony_ci                    container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::REFERENCE), std::move(items)));
472b1994897Sopenharmony_ci                break;
473b1994897Sopenharmony_ci            }
474b1994897Sopenharmony_ci            case 'H': {
475b1994897Sopenharmony_ci                // ARRAY can appear for empty arrays only
476b1994897Sopenharmony_ci                ASSERT(ann_elem.GetArrayValue().GetCount() == 0);
477b1994897Sopenharmony_ci                elem_value_item = static_cast<ValueItem *>(
478b1994897Sopenharmony_ci                    container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::VOID), std::vector<ScalarValueItem>()));
479b1994897Sopenharmony_ci                break;
480b1994897Sopenharmony_ci            }
481b1994897Sopenharmony_ci            case 'Z': {
482b1994897Sopenharmony_ci                auto array = ann_elem.GetArrayValue();
483b1994897Sopenharmony_ci                std::vector<ScalarValueItem> items;
484b1994897Sopenharmony_ci                for (size_t j = 0; j < array.GetCount(); j++) {
485b1994897Sopenharmony_ci                    const File::EntityId ann_item_id {array.Get<uint32_t>(j)};
486b1994897Sopenharmony_ci                    items.emplace_back(CreateAnnotationItem(ann_item_id));
487b1994897Sopenharmony_ci                }
488b1994897Sopenharmony_ci                elem_value_item = static_cast<ValueItem *>(
489b1994897Sopenharmony_ci                    container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::REFERENCE), std::move(items)));
490b1994897Sopenharmony_ci                break;
491b1994897Sopenharmony_ci            }
492b1994897Sopenharmony_ci            case '@': {
493b1994897Sopenharmony_ci                // TODO(nsizov): support it
494b1994897Sopenharmony_ci                LOG(FATAL, PANDAFILE) << "MethodHandle is not supported so far";
495b1994897Sopenharmony_ci                break;
496b1994897Sopenharmony_ci            }
497b1994897Sopenharmony_ci                // array
498b1994897Sopenharmony_ci            case 'I':
499b1994897Sopenharmony_ci                // VOID(I) and ARRAY(H) value should not appear
500b1994897Sopenharmony_ci            default:
501b1994897Sopenharmony_ci                UNREACHABLE();
502b1994897Sopenharmony_ci        }
503b1994897Sopenharmony_ci
504b1994897Sopenharmony_ci        ASSERT(elem_value_item != nullptr);
505b1994897Sopenharmony_ci
506b1994897Sopenharmony_ci        tag_elements.emplace_back(AnnotationItem::Tag(static_cast<char>(ann_tag.GetItem())));
507b1994897Sopenharmony_ci        File::EntityId name_id(ann_elem.GetNameId());
508b1994897Sopenharmony_ci        std::string annot_name_str(utf::Mutf8AsCString(file_->GetStringData(name_id).data));
509b1994897Sopenharmony_ci        auto elem_name_item = container_.GetOrCreateStringItem(annot_name_str);
510b1994897Sopenharmony_ci        item_elements.emplace_back(AnnotationItem::Elem(elem_name_item, elem_value_item));
511b1994897Sopenharmony_ci    }
512b1994897Sopenharmony_ci
513b1994897Sopenharmony_ci    ann_item->SetElements(std::move(item_elements));
514b1994897Sopenharmony_ci    ann_item->SetTags(std::move(tag_elements));
515b1994897Sopenharmony_ci
516b1994897Sopenharmony_ci    return ann_item;
517b1994897Sopenharmony_ci}
518b1994897Sopenharmony_ci
519b1994897Sopenharmony_ciTypeItem *FileReader::CreateParamTypeItem(ProtoDataAccessor *proto_acc, size_t param_num, size_t reference_num)
520b1994897Sopenharmony_ci{
521b1994897Sopenharmony_ci    Type param_type = proto_acc->GetArgType(param_num);
522b1994897Sopenharmony_ci    TypeItem *param_type_item = nullptr;
523b1994897Sopenharmony_ci    if (param_type.IsPrimitive()) {
524b1994897Sopenharmony_ci        param_type_item = container_.GetOrCreatePrimitiveTypeItem(param_type);
525b1994897Sopenharmony_ci    } else {
526b1994897Sopenharmony_ci        const File::EntityId type_cls_id = proto_acc->GetReferenceType(reference_num);
527b1994897Sopenharmony_ci        if (file_->IsExternal(type_cls_id)) {
528b1994897Sopenharmony_ci            param_type_item = CreateForeignClassItem(type_cls_id);
529b1994897Sopenharmony_ci        } else {
530b1994897Sopenharmony_ci            param_type_item = CreateClassItem(type_cls_id);
531b1994897Sopenharmony_ci        }
532b1994897Sopenharmony_ci    }
533b1994897Sopenharmony_ci
534b1994897Sopenharmony_ci    ASSERT(param_type_item != nullptr);
535b1994897Sopenharmony_ci
536b1994897Sopenharmony_ci    return param_type_item;
537b1994897Sopenharmony_ci}
538b1994897Sopenharmony_ci
539b1994897Sopenharmony_cistd::vector<MethodParamItem> FileReader::CreateMethodParamItems(ProtoDataAccessor *proto_acc,
540b1994897Sopenharmony_ci                                                                MethodDataAccessor *method_acc, size_t reference_num)
541b1994897Sopenharmony_ci{
542b1994897Sopenharmony_ci    std::vector<MethodParamItem> param_items;
543b1994897Sopenharmony_ci
544b1994897Sopenharmony_ci    for (size_t i = 0; i < proto_acc->GetNumArgs(); i++) {
545b1994897Sopenharmony_ci        TypeItem *param_type_item = CreateParamTypeItem(proto_acc, i, reference_num);
546b1994897Sopenharmony_ci        if (param_type_item->GetType().IsReference()) {
547b1994897Sopenharmony_ci            reference_num++;
548b1994897Sopenharmony_ci        }
549b1994897Sopenharmony_ci        param_items.emplace_back(MethodParamItem(param_type_item));
550b1994897Sopenharmony_ci    }
551b1994897Sopenharmony_ci
552b1994897Sopenharmony_ci    auto param_ann_id = method_acc->GetParamAnnotationId();
553b1994897Sopenharmony_ci    if (param_ann_id) {
554b1994897Sopenharmony_ci        ParamAnnotationsDataAccessor param_acc(*file_, param_ann_id.value());
555b1994897Sopenharmony_ci        for (size_t i = 0; i < proto_acc->GetNumArgs(); i++) {
556b1994897Sopenharmony_ci            ParamAnnotationsDataAccessor::AnnotationArray ann_arr = param_acc.GetAnnotationArray(i);
557b1994897Sopenharmony_ci            ann_arr.EnumerateAnnotations([&](File::EntityId ann_id) {
558b1994897Sopenharmony_ci                auto ann_item = CreateAnnotationItem(ann_id);
559b1994897Sopenharmony_ci                param_items[i].AddAnnotation(ann_item);
560b1994897Sopenharmony_ci            });
561b1994897Sopenharmony_ci        }
562b1994897Sopenharmony_ci    }
563b1994897Sopenharmony_ci
564b1994897Sopenharmony_ci    auto runtime_param_ann_id = method_acc->GetRuntimeParamAnnotationId();
565b1994897Sopenharmony_ci    if (runtime_param_ann_id) {
566b1994897Sopenharmony_ci        ParamAnnotationsDataAccessor param_acc(*file_, runtime_param_ann_id.value());
567b1994897Sopenharmony_ci        for (size_t i = 0; i < proto_acc->GetNumArgs(); i++) {
568b1994897Sopenharmony_ci            ParamAnnotationsDataAccessor::AnnotationArray ann_arr = param_acc.GetAnnotationArray(i);
569b1994897Sopenharmony_ci            ann_arr.EnumerateAnnotations([&](File::EntityId ann_id) {
570b1994897Sopenharmony_ci                auto ann_item = CreateAnnotationItem(ann_id);
571b1994897Sopenharmony_ci                param_items[i].AddRuntimeAnnotation(ann_item);
572b1994897Sopenharmony_ci            });
573b1994897Sopenharmony_ci        }
574b1994897Sopenharmony_ci    }
575b1994897Sopenharmony_ci
576b1994897Sopenharmony_ci    return param_items;
577b1994897Sopenharmony_ci}
578b1994897Sopenharmony_ci
579b1994897Sopenharmony_ciDebugInfoItem *FileReader::CreateDebugInfoItem(File::EntityId debug_info_id)
580b1994897Sopenharmony_ci{
581b1994897Sopenharmony_ci    auto it = items_done_.find(debug_info_id);
582b1994897Sopenharmony_ci    if (it != items_done_.end()) {
583b1994897Sopenharmony_ci        return static_cast<DebugInfoItem *>(it->second);
584b1994897Sopenharmony_ci    }
585b1994897Sopenharmony_ci
586b1994897Sopenharmony_ci    auto *lnp_item = container_.CreateLineNumberProgramItem();
587b1994897Sopenharmony_ci    auto *debug_info_item = container_.CreateItem<DebugInfoItem>(lnp_item);
588b1994897Sopenharmony_ci    items_done_.insert({debug_info_id, static_cast<BaseItem *>(debug_info_item)});
589b1994897Sopenharmony_ci
590b1994897Sopenharmony_ci    DebugInfoDataAccessor debug_acc(*file_, debug_info_id);
591b1994897Sopenharmony_ci
592b1994897Sopenharmony_ci    debug_info_item->SetLineNumber(debug_acc.GetLineStart());
593b1994897Sopenharmony_ci    debug_acc.EnumerateParameters([&](File::EntityId param_id) {
594b1994897Sopenharmony_ci        auto data = file_->GetStringData(param_id);
595b1994897Sopenharmony_ci        std::string item_str(utf::Mutf8AsCString(data.data));
596b1994897Sopenharmony_ci        auto *string_item = container_.GetOrCreateStringItem(item_str);
597b1994897Sopenharmony_ci        debug_info_item->AddParameter(string_item);
598b1994897Sopenharmony_ci    });
599b1994897Sopenharmony_ci
600b1994897Sopenharmony_ci    return debug_info_item;
601b1994897Sopenharmony_ci}
602b1994897Sopenharmony_ci
603b1994897Sopenharmony_ciTypeItem *FileReader::GetReturnTypeItem(Type ret_type, size_t &reference_num)
604b1994897Sopenharmony_ci{
605b1994897Sopenharmony_ci    TypeItem *ret_type_item = nullptr;
606b1994897Sopenharmony_ci    if (ret_type.IsPrimitive()) {
607b1994897Sopenharmony_ci        ret_type_item = container_.GetOrCreatePrimitiveTypeItem(ret_type);
608b1994897Sopenharmony_ci    } else {
609b1994897Sopenharmony_ci        const File::EntityId type_cls_id = proto_acc.GetReferenceType(reference_num);
610b1994897Sopenharmony_ci        if (file_->IsExternal(type_cls_id)) {
611b1994897Sopenharmony_ci            ret_type_item = CreateForeignClassItem(type_cls_id);
612b1994897Sopenharmony_ci        } else {
613b1994897Sopenharmony_ci            ret_type_item = CreateClassItem(type_cls_id);
614b1994897Sopenharmony_ci        }
615b1994897Sopenharmony_ci        reference_num++;
616b1994897Sopenharmony_ci    }
617b1994897Sopenharmony_ci    return ret_type_item;
618b1994897Sopenharmony_ci}
619b1994897Sopenharmony_ci
620b1994897Sopenharmony_civoid FileReader::EnumerateBlocks(MethodDataAccessor method_acc, MethodItem *method_item)
621b1994897Sopenharmony_ci{
622b1994897Sopenharmony_ci    // quick check
623b1994897Sopenharmony_ci    auto code_id = method_acc.GetCodeId();
624b1994897Sopenharmony_ci    if (code_id == std::nullopt) {
625b1994897Sopenharmony_ci        return;
626b1994897Sopenharmony_ci    }
627b1994897Sopenharmony_ci
628b1994897Sopenharmony_ci    CodeDataAccessor code_acc(*file_, code_id.value());
629b1994897Sopenharmony_ci    std::vector<uint8_t> instructions(code_acc.GetCodeSize());
630b1994897Sopenharmony_ci    // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
631b1994897Sopenharmony_ci    instructions.assign(code_acc.GetInstructions(), code_acc.GetInstructions() + code_acc.GetCodeSize());
632b1994897Sopenharmony_ci    auto *code_item =
633b1994897Sopenharmony_ci        container_.CreateItem<CodeItem>(code_acc.GetNumVregs(), code_acc.GetNumArgs(), std::move(instructions));
634b1994897Sopenharmony_ci
635b1994897Sopenharmony_ci    code_acc.EnumerateTryBlocks([&](CodeDataAccessor::TryBlock &try_block) {
636b1994897Sopenharmony_ci        std::vector<CodeItem::CatchBlock> catch_blocks;
637b1994897Sopenharmony_ci        try_block.EnumerateCatchBlocks([&](CodeDataAccessor::CatchBlock &catch_block) {
638b1994897Sopenharmony_ci            BaseClassItem *catch_type_item = nullptr;
639b1994897Sopenharmony_ci            auto type_idx = catch_block.GetTypeIdx();
640b1994897Sopenharmony_ci            if (type_idx != panda_file::INVALID_INDEX) {
641b1994897Sopenharmony_ci                File::EntityId catch_cls_id = file_->ResolveClassIndex(method_id, catch_block.GetTypeIdx());
642b1994897Sopenharmony_ci                catch_type_item = (file_->IsExternal(catch_cls_id)) ? CreateForeignClassItem(catch_cls_id) :
643b1994897Sopenharmony_ci                                                                      CreateClassItem(catch_cls_id);
644b1994897Sopenharmony_ci                method_item->AddIndexDependency(catch_type_item);
645b1994897Sopenharmony_ci            }
646b1994897Sopenharmony_ci            // Add new CatchBlock
647b1994897Sopenharmony_ci            catch_blocks.emplace_back(CodeItem::CatchBlock(method_item, catch_type_item, catch_block.GetHandlerPc(),
648b1994897Sopenharmony_ci                                                           catch_block.GetCodeSize()));
649b1994897Sopenharmony_ci            return true;
650b1994897Sopenharmony_ci        });
651b1994897Sopenharmony_ci        code_item->AddTryBlock(
652b1994897Sopenharmony_ci            CodeItem::TryBlock(try_block.GetStartPc(), try_block.GetLength(), std::move(catch_blocks)));
653b1994897Sopenharmony_ci        return true;
654b1994897Sopenharmony_ci    });
655b1994897Sopenharmony_ci
656b1994897Sopenharmony_ci    method_item->SetCode(code_item);
657b1994897Sopenharmony_ci}
658b1994897Sopenharmony_ci
659b1994897Sopenharmony_ciMethodItem *FileReader::CreateMethodItem(ClassItem *cls, File::EntityId method_id)
660b1994897Sopenharmony_ci{
661b1994897Sopenharmony_ci    // Check if we have done this method
662b1994897Sopenharmony_ci    auto it = items_done_.find(method_id);
663b1994897Sopenharmony_ci    if (it != items_done_.end()) {
664b1994897Sopenharmony_ci        return static_cast<MethodItem *>(it->second);
665b1994897Sopenharmony_ci    }
666b1994897Sopenharmony_ci
667b1994897Sopenharmony_ci    MethodDataAccessor method_acc(*file_, method_id);
668b1994897Sopenharmony_ci    auto data = file_->GetStringData(method_acc.GetNameId());
669b1994897Sopenharmony_ci    std::string method_name(utf::Mutf8AsCString(data.data));
670b1994897Sopenharmony_ci    auto method_str_item = container_.GetOrCreateStringItem(method_name);
671b1994897Sopenharmony_ci
672b1994897Sopenharmony_ci    ProtoDataAccessor proto_acc(*file_, method_acc.GetProtoId());
673b1994897Sopenharmony_ci    Type ret_type = proto_acc.GetReturnType();
674b1994897Sopenharmony_ci    size_t reference_num = 0;
675b1994897Sopenharmony_ci    TypeItem *ret_type_item = GetReturnTypeItem(ret_type, reference_num);
676b1994897Sopenharmony_ci    ASSERT(ret_type_item != nullptr);
677b1994897Sopenharmony_ci    auto param_items = CreateMethodParamItems(&proto_acc, &method_acc, reference_num);
678b1994897Sopenharmony_ci
679b1994897Sopenharmony_ci    // Double check if we have done this method while computing params
680b1994897Sopenharmony_ci    auto it_check = items_done_.find(method_id);
681b1994897Sopenharmony_ci    if (it_check != items_done_.end()) {
682b1994897Sopenharmony_ci        return static_cast<MethodItem *>(it_check->second);
683b1994897Sopenharmony_ci    }
684b1994897Sopenharmony_ci
685b1994897Sopenharmony_ci    auto proto_item = container_.GetOrCreateProtoItem(ret_type_item, param_items);
686b1994897Sopenharmony_ci    auto method_item =
687b1994897Sopenharmony_ci        cls->AddMethod(method_str_item, proto_item, method_acc.GetAccessFlags(), std::move(param_items));
688b1994897Sopenharmony_ci    if (method_item->HasRuntimeParamAnnotations()) {
689b1994897Sopenharmony_ci        container_.CreateItem<ParamAnnotationsItem>(method_item, true);
690b1994897Sopenharmony_ci    }
691b1994897Sopenharmony_ci
692b1994897Sopenharmony_ci    if (method_item->HasParamAnnotations()) {
693b1994897Sopenharmony_ci        container_.CreateItem<ParamAnnotationsItem>(method_item, false);
694b1994897Sopenharmony_ci    }
695b1994897Sopenharmony_ci    items_done_.insert({method_id, static_cast<BaseItem *>(method_item)});
696b1994897Sopenharmony_ci
697b1994897Sopenharmony_ci    method_acc.EnumerateAnnotations(
698b1994897Sopenharmony_ci        [&](File::EntityId ann_id) { method_item->AddAnnotation(CreateAnnotationItem(ann_id)); });
699b1994897Sopenharmony_ci
700b1994897Sopenharmony_ci    method_acc.EnumerateRuntimeAnnotations(
701b1994897Sopenharmony_ci        [&](File::EntityId ann_id) { method_item->AddRuntimeAnnotation(CreateAnnotationItem(ann_id)); });
702b1994897Sopenharmony_ci
703b1994897Sopenharmony_ci    method_acc.EnumerateTypeAnnotations(
704b1994897Sopenharmony_ci        [&](File::EntityId ann_id) { method_item->AddTypeAnnotation(CreateAnnotationItem(ann_id)); });
705b1994897Sopenharmony_ci
706b1994897Sopenharmony_ci    method_acc.EnumerateRuntimeTypeAnnotations(
707b1994897Sopenharmony_ci        [&](File::EntityId ann_id) { method_item->AddRuntimeTypeAnnotation(CreateAnnotationItem(ann_id)); });
708b1994897Sopenharmony_ci
709b1994897Sopenharmony_ci    EnumerateBlocks(method_acc, method_item);
710b1994897Sopenharmony_ci
711b1994897Sopenharmony_ci    auto debug_info_id = method_acc.GetDebugInfoId();
712b1994897Sopenharmony_ci    if (debug_info_id) {
713b1994897Sopenharmony_ci        method_item->SetDebugInfo(CreateDebugInfoItem(debug_info_id.value()));
714b1994897Sopenharmony_ci    }
715b1994897Sopenharmony_ci
716b1994897Sopenharmony_ci    auto source_lang = method_acc.GetSourceLang();
717b1994897Sopenharmony_ci    if (source_lang) {
718b1994897Sopenharmony_ci        method_item->SetSourceLang(source_lang.value());
719b1994897Sopenharmony_ci    }
720b1994897Sopenharmony_ci
721b1994897Sopenharmony_ci    return method_item;
722b1994897Sopenharmony_ci}
723b1994897Sopenharmony_ci
724b1994897Sopenharmony_ciMethodHandleItem *FileReader::CreateMethodHandleItem(File::EntityId mh_id)
725b1994897Sopenharmony_ci{
726b1994897Sopenharmony_ci    (void)mh_id;
727b1994897Sopenharmony_ci    ASSERT(false);
728b1994897Sopenharmony_ci    return nullptr;  // STUB
729b1994897Sopenharmony_ci}
730b1994897Sopenharmony_ci
731b1994897Sopenharmony_ciFieldItem *FileReader::CreateFieldItem(ClassItem *cls, File::EntityId field_id)
732b1994897Sopenharmony_ci{
733b1994897Sopenharmony_ci    auto it = items_done_.find(field_id);
734b1994897Sopenharmony_ci    if (it != items_done_.end()) {
735b1994897Sopenharmony_ci        return static_cast<FieldItem *>(it->second);
736b1994897Sopenharmony_ci    }
737b1994897Sopenharmony_ci
738b1994897Sopenharmony_ci    FieldDataAccessor field_acc(*file_, field_id);
739b1994897Sopenharmony_ci
740b1994897Sopenharmony_ci    auto data = file_->GetStringData(field_acc.GetNameId());
741b1994897Sopenharmony_ci    std::string string_name(utf::Mutf8AsCString(data.data));
742b1994897Sopenharmony_ci    auto *field_name = container_.GetOrCreateStringItem(string_name);
743b1994897Sopenharmony_ci    Type field_type = Type::GetTypeFromFieldEncoding(field_acc.GetType());
744b1994897Sopenharmony_ci
745b1994897Sopenharmony_ci    TypeItem *field_type_item = nullptr;
746b1994897Sopenharmony_ci    if (field_type.IsReference()) {
747b1994897Sopenharmony_ci        File::EntityId type_id(field_acc.GetType());
748b1994897Sopenharmony_ci        if (file_->IsExternal(type_id)) {
749b1994897Sopenharmony_ci            field_type_item = CreateForeignClassItem(type_id);
750b1994897Sopenharmony_ci        } else {
751b1994897Sopenharmony_ci            field_type_item = CreateClassItem(type_id);
752b1994897Sopenharmony_ci            // Double check if we done this field while generated class item
753b1994897Sopenharmony_ci            auto it_check = items_done_.find(field_id);
754b1994897Sopenharmony_ci            if (it_check != items_done_.end()) {
755b1994897Sopenharmony_ci                return static_cast<FieldItem *>(it_check->second);
756b1994897Sopenharmony_ci            }
757b1994897Sopenharmony_ci        }
758b1994897Sopenharmony_ci    } else {
759b1994897Sopenharmony_ci        field_type_item = container_.GetOrCreatePrimitiveTypeItem(field_type.GetId());
760b1994897Sopenharmony_ci    }
761b1994897Sopenharmony_ci
762b1994897Sopenharmony_ci    ASSERT(field_type_item != nullptr);
763b1994897Sopenharmony_ci
764b1994897Sopenharmony_ci    FieldItem *field_item = cls->AddField(field_name, field_type_item, field_acc.GetAccessFlags());
765b1994897Sopenharmony_ci    items_done_.insert({field_id, static_cast<BaseItem *>(field_item)});
766b1994897Sopenharmony_ci
767b1994897Sopenharmony_ci    switch (field_type.GetId()) {
768b1994897Sopenharmony_ci        case Type::TypeId::U1:
769b1994897Sopenharmony_ci        case Type::TypeId::I8:
770b1994897Sopenharmony_ci        case Type::TypeId::U8:
771b1994897Sopenharmony_ci            SetIntegerFieldValue<uint8_t>(&field_acc, field_item);
772b1994897Sopenharmony_ci            break;
773b1994897Sopenharmony_ci        case Type::TypeId::I16:
774b1994897Sopenharmony_ci        case Type::TypeId::U16:
775b1994897Sopenharmony_ci            SetIntegerFieldValue<uint16_t>(&field_acc, field_item);
776b1994897Sopenharmony_ci            break;
777b1994897Sopenharmony_ci        case Type::TypeId::I32:
778b1994897Sopenharmony_ci        case Type::TypeId::U32:
779b1994897Sopenharmony_ci            SetIntegerFieldValue<uint32_t>(&field_acc, field_item);
780b1994897Sopenharmony_ci            break;
781b1994897Sopenharmony_ci        case Type::TypeId::I64:
782b1994897Sopenharmony_ci        case Type::TypeId::U64:
783b1994897Sopenharmony_ci            SetIntegerFieldValue<uint64_t>(&field_acc, field_item);
784b1994897Sopenharmony_ci            break;
785b1994897Sopenharmony_ci        case Type::TypeId::F32:
786b1994897Sopenharmony_ci            SetFloatFieldValue<float>(&field_acc, field_item);
787b1994897Sopenharmony_ci            break;
788b1994897Sopenharmony_ci        case Type::TypeId::F64:
789b1994897Sopenharmony_ci            SetFloatFieldValue<double>(&field_acc, field_item);
790b1994897Sopenharmony_ci            break;
791b1994897Sopenharmony_ci        case Type::TypeId::REFERENCE:
792b1994897Sopenharmony_ci            SetStringFieldValue(&field_acc, field_item);
793b1994897Sopenharmony_ci            break;
794b1994897Sopenharmony_ci        case Type::TypeId::TAGGED:
795b1994897Sopenharmony_ci        default:
796b1994897Sopenharmony_ci            UNREACHABLE();
797b1994897Sopenharmony_ci            break;
798b1994897Sopenharmony_ci    }
799b1994897Sopenharmony_ci
800b1994897Sopenharmony_ci    field_acc.EnumerateAnnotations(
801b1994897Sopenharmony_ci        [&](File::EntityId ann_id) { field_item->AddAnnotation(CreateAnnotationItem(ann_id)); });
802b1994897Sopenharmony_ci
803b1994897Sopenharmony_ci    field_acc.EnumerateRuntimeAnnotations(
804b1994897Sopenharmony_ci        [&](File::EntityId ann_id) { field_item->AddRuntimeAnnotation(CreateAnnotationItem(ann_id)); });
805b1994897Sopenharmony_ci
806b1994897Sopenharmony_ci    field_acc.EnumerateRuntimeTypeAnnotations(
807b1994897Sopenharmony_ci        [&](File::EntityId ann_id) { field_item->AddRuntimeTypeAnnotation(CreateAnnotationItem(ann_id)); });
808b1994897Sopenharmony_ci
809b1994897Sopenharmony_ci    field_acc.EnumerateTypeAnnotations(
810b1994897Sopenharmony_ci        [&](File::EntityId ann_id) { field_item->AddTypeAnnotation(CreateAnnotationItem(ann_id)); });
811b1994897Sopenharmony_ci
812b1994897Sopenharmony_ci    return field_item;
813b1994897Sopenharmony_ci}
814b1994897Sopenharmony_ci
815b1994897Sopenharmony_ciForeignMethodItem *FileReader::CreateForeignMethodItem(BaseClassItem *fcls, File::EntityId method_id)
816b1994897Sopenharmony_ci{
817b1994897Sopenharmony_ci    auto it = items_done_.find(method_id);
818b1994897Sopenharmony_ci    if (it != items_done_.end()) {
819b1994897Sopenharmony_ci        return static_cast<ForeignMethodItem *>(it->second);
820b1994897Sopenharmony_ci    }
821b1994897Sopenharmony_ci
822b1994897Sopenharmony_ci    MethodDataAccessor method_acc(*file_, method_id);
823b1994897Sopenharmony_ci    auto data = file_->GetStringData(method_acc.GetNameId());
824b1994897Sopenharmony_ci    std::string method_name(utf::Mutf8AsCString(data.data));
825b1994897Sopenharmony_ci    auto *method_str_item = container_.GetOrCreateStringItem(method_name);
826b1994897Sopenharmony_ci
827b1994897Sopenharmony_ci    ProtoDataAccessor proto_acc(*file_, method_acc.GetProtoId());
828b1994897Sopenharmony_ci    Type ret_type = proto_acc.GetReturnType();
829b1994897Sopenharmony_ci    size_t reference_num = 0;
830b1994897Sopenharmony_ci    TypeItem *ret_type_item = nullptr;
831b1994897Sopenharmony_ci    if (ret_type.IsPrimitive()) {
832b1994897Sopenharmony_ci        ret_type_item = container_.GetOrCreatePrimitiveTypeItem(ret_type);
833b1994897Sopenharmony_ci    } else {
834b1994897Sopenharmony_ci        const File::EntityId type_cls_id = proto_acc.GetReferenceType(reference_num);
835b1994897Sopenharmony_ci        if (file_->IsExternal(type_cls_id)) {
836b1994897Sopenharmony_ci            ret_type_item = CreateForeignClassItem(type_cls_id);
837b1994897Sopenharmony_ci        } else {
838b1994897Sopenharmony_ci            ret_type_item = CreateClassItem(type_cls_id);
839b1994897Sopenharmony_ci        }
840b1994897Sopenharmony_ci        reference_num++;
841b1994897Sopenharmony_ci    }
842b1994897Sopenharmony_ci    ASSERT(ret_type_item != nullptr);
843b1994897Sopenharmony_ci    auto param_items = CreateMethodParamItems(&proto_acc, &method_acc, reference_num);
844b1994897Sopenharmony_ci    // Double check if we done this method while computing params
845b1994897Sopenharmony_ci    auto it_check = items_done_.find(method_id);
846b1994897Sopenharmony_ci    if (it_check != items_done_.end()) {
847b1994897Sopenharmony_ci        return static_cast<ForeignMethodItem *>(it_check->second);
848b1994897Sopenharmony_ci    }
849b1994897Sopenharmony_ci    auto *proto_item = container_.GetOrCreateProtoItem(ret_type_item, param_items);
850b1994897Sopenharmony_ci
851b1994897Sopenharmony_ci    auto *method_item =
852b1994897Sopenharmony_ci        container_.CreateItem<ForeignMethodItem>(fcls, method_str_item, proto_item, method_acc.GetAccessFlags());
853b1994897Sopenharmony_ci
854b1994897Sopenharmony_ci    items_done_.insert({method_id, static_cast<BaseItem *>(method_item)});
855b1994897Sopenharmony_ci
856b1994897Sopenharmony_ci    return method_item;
857b1994897Sopenharmony_ci}
858b1994897Sopenharmony_ci
859b1994897Sopenharmony_ciForeignFieldItem *FileReader::CreateForeignFieldItem(BaseClassItem *fcls, File::EntityId field_id)
860b1994897Sopenharmony_ci{
861b1994897Sopenharmony_ci    auto it = items_done_.find(field_id);
862b1994897Sopenharmony_ci    if (it != items_done_.end()) {
863b1994897Sopenharmony_ci        return static_cast<ForeignFieldItem *>(it->second);
864b1994897Sopenharmony_ci    }
865b1994897Sopenharmony_ci
866b1994897Sopenharmony_ci    FieldDataAccessor field_acc(*file_, field_id);
867b1994897Sopenharmony_ci
868b1994897Sopenharmony_ci    auto data = file_->GetStringData(field_acc.GetNameId());
869b1994897Sopenharmony_ci    std::string string_name(utf::Mutf8AsCString(data.data));
870b1994897Sopenharmony_ci    auto *field_name = container_.GetOrCreateStringItem(string_name);
871b1994897Sopenharmony_ci    Type field_type = Type::GetTypeFromFieldEncoding(field_acc.GetType());
872b1994897Sopenharmony_ci    TypeItem *field_type_item = nullptr;
873b1994897Sopenharmony_ci    if (field_type.IsReference()) {
874b1994897Sopenharmony_ci        File::EntityId type_id(field_acc.GetType());
875b1994897Sopenharmony_ci        if (file_->IsExternal(type_id)) {
876b1994897Sopenharmony_ci            field_type_item = CreateForeignClassItem(type_id);
877b1994897Sopenharmony_ci        } else {
878b1994897Sopenharmony_ci            field_type_item = CreateClassItem(type_id);
879b1994897Sopenharmony_ci            // Double check if we done this field while generated class item
880b1994897Sopenharmony_ci            auto it_check = items_done_.find(field_id);
881b1994897Sopenharmony_ci            if (it_check != items_done_.end()) {
882b1994897Sopenharmony_ci                return static_cast<ForeignFieldItem *>(it_check->second);
883b1994897Sopenharmony_ci            }
884b1994897Sopenharmony_ci        }
885b1994897Sopenharmony_ci    } else {
886b1994897Sopenharmony_ci        field_type_item = container_.GetOrCreatePrimitiveTypeItem(field_type.GetId());
887b1994897Sopenharmony_ci    }
888b1994897Sopenharmony_ci
889b1994897Sopenharmony_ci    ASSERT(field_type_item != nullptr);
890b1994897Sopenharmony_ci
891b1994897Sopenharmony_ci    auto *field_item = container_.CreateItem<ForeignFieldItem>(fcls, field_name, field_type_item);
892b1994897Sopenharmony_ci    items_done_.insert({field_id, static_cast<BaseItem *>(field_item)});
893b1994897Sopenharmony_ci
894b1994897Sopenharmony_ci    return field_item;
895b1994897Sopenharmony_ci}
896b1994897Sopenharmony_ci
897b1994897Sopenharmony_ciForeignClassItem *FileReader::CreateForeignClassItem(File::EntityId class_id)
898b1994897Sopenharmony_ci{
899b1994897Sopenharmony_ci    auto it = items_done_.find(class_id);
900b1994897Sopenharmony_ci    if (it != items_done_.end()) {
901b1994897Sopenharmony_ci        return static_cast<ForeignClassItem *>(it->second);
902b1994897Sopenharmony_ci    }
903b1994897Sopenharmony_ci
904b1994897Sopenharmony_ci    std::string class_name(utf::Mutf8AsCString(file_->GetStringData(class_id).data));
905b1994897Sopenharmony_ci    auto *class_item = container_.GetOrCreateForeignClassItem(class_name);
906b1994897Sopenharmony_ci
907b1994897Sopenharmony_ci    items_done_.insert({class_id, static_cast<BaseItem *>(class_item)});
908b1994897Sopenharmony_ci
909b1994897Sopenharmony_ci    return class_item;
910b1994897Sopenharmony_ci}
911b1994897Sopenharmony_ci
912b1994897Sopenharmony_civoid FileReader::CreateSuperClassItem(ClassDataAccessor& class_acc,
913b1994897Sopenharmony_ci                                      ClassItem* class_item,
914b1994897Sopenharmony_ci                                      const std::string& class_name)
915b1994897Sopenharmony_ci{
916b1994897Sopenharmony_ci    auto super_class_id = class_acc.GetSuperClassId();
917b1994897Sopenharmony_ci    if (super_class_id.GetOffset() != 0) {
918b1994897Sopenharmony_ci        if (super_class_id.GetOffset() == class_id.GetOffset()) {
919b1994897Sopenharmony_ci            LOG(FATAL, PANDAFILE) << "Class " << class_name << " has cyclic inheritance";
920b1994897Sopenharmony_ci        }
921b1994897Sopenharmony_ci
922b1994897Sopenharmony_ci        if (file_->IsExternal(super_class_id)) {
923b1994897Sopenharmony_ci            auto *super_class_item = CreateForeignClassItem(super_class_id);
924b1994897Sopenharmony_ci            class_item->SetSuperClass(super_class_item);
925b1994897Sopenharmony_ci        } else {
926b1994897Sopenharmony_ci            auto *super_class_item = CreateClassItem(super_class_id);
927b1994897Sopenharmony_ci            class_item->SetSuperClass(super_class_item);
928b1994897Sopenharmony_ci        }
929b1994897Sopenharmony_ci    }
930b1994897Sopenharmony_ci}
931b1994897Sopenharmony_ci
932b1994897Sopenharmony_ciClassItem *FileReader::CreateClassItem(File::EntityId class_id)
933b1994897Sopenharmony_ci{
934b1994897Sopenharmony_ci    auto it = items_done_.find(class_id);
935b1994897Sopenharmony_ci    if (it != items_done_.end()) {
936b1994897Sopenharmony_ci        return static_cast<ClassItem *>(it->second);
937b1994897Sopenharmony_ci    }
938b1994897Sopenharmony_ci    ClassDataAccessor class_acc(*file_, class_id);
939b1994897Sopenharmony_ci
940b1994897Sopenharmony_ci    std::string class_name(utf::Mutf8AsCString(file_->GetStringData(class_id).data));
941b1994897Sopenharmony_ci    auto *class_item = container_.GetOrCreateClassItem(class_name);
942b1994897Sopenharmony_ci
943b1994897Sopenharmony_ci    items_done_.insert({class_id, static_cast<BaseItem *>(class_item)});
944b1994897Sopenharmony_ci
945b1994897Sopenharmony_ci    class_item->SetAccessFlags(class_acc.GetAccessFlags());
946b1994897Sopenharmony_ci
947b1994897Sopenharmony_ci    auto source_lang_opt = class_acc.GetSourceLang();
948b1994897Sopenharmony_ci    if (source_lang_opt) {
949b1994897Sopenharmony_ci        class_item->SetSourceLang(source_lang_opt.value());
950b1994897Sopenharmony_ci    }
951b1994897Sopenharmony_ci
952b1994897Sopenharmony_ci    CreateSuperClassItem(class_acc, class_item, class_name);
953b1994897Sopenharmony_ci
954b1994897Sopenharmony_ci    class_acc.EnumerateInterfaces([&](File::EntityId iface_id) {
955b1994897Sopenharmony_ci        if (file_->IsExternal(iface_id)) {
956b1994897Sopenharmony_ci            class_item->AddInterface(CreateForeignClassItem(iface_id));
957b1994897Sopenharmony_ci        } else {
958b1994897Sopenharmony_ci            class_item->AddInterface(CreateClassItem(iface_id));
959b1994897Sopenharmony_ci        }
960b1994897Sopenharmony_ci    });
961b1994897Sopenharmony_ci
962b1994897Sopenharmony_ci    class_acc.EnumerateAnnotations(
963b1994897Sopenharmony_ci        [&](File::EntityId ann_id) { class_item->AddAnnotation(CreateAnnotationItem(ann_id)); });
964b1994897Sopenharmony_ci
965b1994897Sopenharmony_ci    class_acc.EnumerateRuntimeAnnotations(
966b1994897Sopenharmony_ci        [&](File::EntityId ann_id) { class_item->AddRuntimeAnnotation(CreateAnnotationItem(ann_id)); });
967b1994897Sopenharmony_ci
968b1994897Sopenharmony_ci    class_acc.EnumerateTypeAnnotations(
969b1994897Sopenharmony_ci        [&](File::EntityId ann_id) { class_item->AddTypeAnnotation(CreateAnnotationItem(ann_id)); });
970b1994897Sopenharmony_ci
971b1994897Sopenharmony_ci    class_acc.EnumerateFields(
972b1994897Sopenharmony_ci        [&](FieldDataAccessor &field_acc) { CreateFieldItem(class_item, field_acc.GetFieldId()); });
973b1994897Sopenharmony_ci
974b1994897Sopenharmony_ci    class_acc.EnumerateMethods(
975b1994897Sopenharmony_ci        [&](MethodDataAccessor &method_acc) { CreateMethodItem(class_item, method_acc.GetMethodId()); });
976b1994897Sopenharmony_ci
977b1994897Sopenharmony_ci    auto source_file_id = class_acc.GetSourceFileId();
978b1994897Sopenharmony_ci    if (source_file_id) {
979b1994897Sopenharmony_ci        std::string source_file = utf::Mutf8AsCString(file_->GetStringData(source_file_id.value()).data);
980b1994897Sopenharmony_ci        class_item->SetSourceFile(container_.GetOrCreateStringItem(source_file));
981b1994897Sopenharmony_ci    }
982b1994897Sopenharmony_ci
983b1994897Sopenharmony_ci    ASSERT(class_item != nullptr);
984b1994897Sopenharmony_ci
985b1994897Sopenharmony_ci    return class_item;
986b1994897Sopenharmony_ci}
987b1994897Sopenharmony_ci
988b1994897Sopenharmony_cibool FileReader::ReadLiteralArrayItems()
989b1994897Sopenharmony_ci{
990b1994897Sopenharmony_ci    const auto lit_arrays_id = file_->GetLiteralArraysId();
991b1994897Sopenharmony_ci    LiteralDataAccessor lit_array_accessor(*file_, lit_arrays_id);
992b1994897Sopenharmony_ci    size_t num_litarrays = lit_array_accessor.GetLiteralNum();
993b1994897Sopenharmony_ci
994b1994897Sopenharmony_ci    for (size_t i = 0; i < num_litarrays; i++) {
995b1994897Sopenharmony_ci        auto id = lit_array_accessor.GetLiteralArrayId(i);
996b1994897Sopenharmony_ci        lit_array_accessor.EnumerateLiteralVals(
997b1994897Sopenharmony_ci            id, [id, this](const panda_file::LiteralDataAccessor::LiteralValue &value,
998b1994897Sopenharmony_ci                           const panda_file::LiteralTag &tag) { CreateLiteralArrayItem(value, tag, id); });
999b1994897Sopenharmony_ci    }
1000b1994897Sopenharmony_ci
1001b1994897Sopenharmony_ci    return true;
1002b1994897Sopenharmony_ci}
1003b1994897Sopenharmony_ci
1004b1994897Sopenharmony_cibool FileReader::ReadIndexHeaders()
1005b1994897Sopenharmony_ci{
1006b1994897Sopenharmony_ci    auto index_headers = file_->GetIndexHeaders();
1007b1994897Sopenharmony_ci    for (const auto &header : index_headers) {
1008b1994897Sopenharmony_ci        auto method_index = file_->GetMethodIndex(&header);
1009b1994897Sopenharmony_ci        for (auto method_id : method_index) {
1010b1994897Sopenharmony_ci            MethodDataAccessor method_acc(*file_, method_id);
1011b1994897Sopenharmony_ci            File::EntityId class_id(method_acc.GetClassId());
1012b1994897Sopenharmony_ci            if (file_->IsExternal(class_id)) {
1013b1994897Sopenharmony_ci                auto *fclass_item = CreateForeignClassItem(class_id);
1014b1994897Sopenharmony_ci                ASSERT(file_->IsExternal(method_id));
1015b1994897Sopenharmony_ci                if (CreateForeignMethodItem(fclass_item, method_id) == nullptr) {
1016b1994897Sopenharmony_ci                    return false;
1017b1994897Sopenharmony_ci                }
1018b1994897Sopenharmony_ci            } else {
1019b1994897Sopenharmony_ci                auto *class_item = CreateClassItem(class_id);
1020b1994897Sopenharmony_ci                if (file_->IsExternal(method_id)) {
1021b1994897Sopenharmony_ci                    if (CreateForeignMethodItem(class_item, method_id) == nullptr) {
1022b1994897Sopenharmony_ci                        return false;
1023b1994897Sopenharmony_ci                    }
1024b1994897Sopenharmony_ci                } else if (CreateMethodItem(class_item, method_id) == nullptr) {
1025b1994897Sopenharmony_ci                    return false;
1026b1994897Sopenharmony_ci                }
1027b1994897Sopenharmony_ci            }
1028b1994897Sopenharmony_ci        }
1029b1994897Sopenharmony_ci        auto field_index = file_->GetFieldIndex(&header);
1030b1994897Sopenharmony_ci        for (auto field_id : field_index) {
1031b1994897Sopenharmony_ci            FieldDataAccessor field_acc(*file_, field_id);
1032b1994897Sopenharmony_ci            File::EntityId class_id(field_acc.GetClassId());
1033b1994897Sopenharmony_ci            if (file_->IsExternal(class_id)) {
1034b1994897Sopenharmony_ci                ASSERT(file_->IsExternal(field_id));
1035b1994897Sopenharmony_ci                auto *fclass_item = CreateForeignClassItem(field_acc.GetClassId());
1036b1994897Sopenharmony_ci                if (CreateForeignFieldItem(fclass_item, field_id) == nullptr) {
1037b1994897Sopenharmony_ci                    return false;
1038b1994897Sopenharmony_ci                }
1039b1994897Sopenharmony_ci            } else {
1040b1994897Sopenharmony_ci                auto *class_item = CreateClassItem(field_acc.GetClassId());
1041b1994897Sopenharmony_ci                if (file_->IsExternal(field_id)) {
1042b1994897Sopenharmony_ci                    if (CreateForeignFieldItem(class_item, field_id) == nullptr) {
1043b1994897Sopenharmony_ci                        return false;
1044b1994897Sopenharmony_ci                    }
1045b1994897Sopenharmony_ci                } else if (CreateFieldItem(class_item, field_id) == nullptr) {
1046b1994897Sopenharmony_ci                    return false;
1047b1994897Sopenharmony_ci                }
1048b1994897Sopenharmony_ci            }
1049b1994897Sopenharmony_ci        }
1050b1994897Sopenharmony_ci    }
1051b1994897Sopenharmony_ci    return true;
1052b1994897Sopenharmony_ci}
1053b1994897Sopenharmony_ci
1054b1994897Sopenharmony_cibool FileReader::ReadClasses()
1055b1994897Sopenharmony_ci{
1056b1994897Sopenharmony_ci    const auto class_idx = file_->GetClasses();
1057b1994897Sopenharmony_ci
1058b1994897Sopenharmony_ci    for (unsigned int id : class_idx) {
1059b1994897Sopenharmony_ci        File::EntityId eid(id);
1060b1994897Sopenharmony_ci        if (file_->IsExternal(eid)) {
1061b1994897Sopenharmony_ci            CreateForeignClassItem(eid);
1062b1994897Sopenharmony_ci        } else {
1063b1994897Sopenharmony_ci            CreateClassItem(eid);
1064b1994897Sopenharmony_ci        }
1065b1994897Sopenharmony_ci    }
1066b1994897Sopenharmony_ci
1067b1994897Sopenharmony_ci    return true;
1068b1994897Sopenharmony_ci}
1069b1994897Sopenharmony_ci
1070b1994897Sopenharmony_civoid FileReader::UpdateDebugInfoDependecies(File::EntityId debug_info_id)
1071b1994897Sopenharmony_ci{
1072b1994897Sopenharmony_ci    DebugInfoDataAccessor debug_acc(*file_, debug_info_id);
1073b1994897Sopenharmony_ci    const uint8_t *program = debug_acc.GetLineNumberProgram();
1074b1994897Sopenharmony_ci    auto size = file_->GetSpanFromId(file_->GetIdFromPointer(program)).size();
1075b1994897Sopenharmony_ci    auto opcode_sp = Span(program, size);
1076b1994897Sopenharmony_ci
1077b1994897Sopenharmony_ci    size_t i = 0;
1078b1994897Sopenharmony_ci    LineNumberProgramItem::Opcode opcode;
1079b1994897Sopenharmony_ci    panda_file::LineProgramState state(*file_, File::EntityId(0), debug_acc.GetLineStart(),
1080b1994897Sopenharmony_ci                                       debug_acc.GetConstantPool());
1081b1994897Sopenharmony_ci    while ((opcode = LineNumberProgramItem::Opcode(opcode_sp[i++])) != LineNumberProgramItem::Opcode::END_SEQUENCE) {
1082b1994897Sopenharmony_ci        switch (opcode) {
1083b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::ADVANCE_PC:
1084b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::ADVANCE_LINE:
1085b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::SET_PROLOGUE_END:
1086b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::SET_EPILOGUE_BEGIN: {
1087b1994897Sopenharmony_ci                break;
1088b1994897Sopenharmony_ci            }
1089b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::START_LOCAL: {
1090b1994897Sopenharmony_ci                [[maybe_unused]] int32_t reg_number;
1091b1994897Sopenharmony_ci                size_t n;
1092b1994897Sopenharmony_ci                bool is_full;
1093b1994897Sopenharmony_ci                std::tie(reg_number, n, is_full) = leb128::DecodeSigned<int32_t>(&opcode_sp[i]);
1094b1994897Sopenharmony_ci                LOG_IF(!is_full, FATAL, COMMON) << "Cannot read a register number";
1095b1994897Sopenharmony_ci                i += n;
1096b1994897Sopenharmony_ci
1097b1994897Sopenharmony_ci                auto name_id = File::EntityId(state.ReadULeb128());
1098b1994897Sopenharmony_ci                std::string name = utf::Mutf8AsCString(file_->GetStringData(name_id).data);
1099b1994897Sopenharmony_ci                container_.GetOrCreateStringItem(name);
1100b1994897Sopenharmony_ci
1101b1994897Sopenharmony_ci                auto type_id = File::EntityId(state.ReadULeb128());
1102b1994897Sopenharmony_ci                std::string type_name = utf::Mutf8AsCString(file_->GetStringData(type_id).data);
1103b1994897Sopenharmony_ci                if (file_->IsExternal(type_id)) {
1104b1994897Sopenharmony_ci                    container_.GetOrCreateForeignClassItem(type_name);
1105b1994897Sopenharmony_ci                } else {
1106b1994897Sopenharmony_ci                    container_.GetOrCreateClassItem(type_name);
1107b1994897Sopenharmony_ci                }
1108b1994897Sopenharmony_ci                break;
1109b1994897Sopenharmony_ci            }
1110b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::START_LOCAL_EXTENDED: {
1111b1994897Sopenharmony_ci                [[maybe_unused]] int32_t reg_number;
1112b1994897Sopenharmony_ci                size_t n;
1113b1994897Sopenharmony_ci                bool is_full;
1114b1994897Sopenharmony_ci                std::tie(reg_number, n, is_full) = leb128::DecodeSigned<int32_t>(&opcode_sp[i]);
1115b1994897Sopenharmony_ci                LOG_IF(!is_full, FATAL, COMMON) << "Cannot read a register number";
1116b1994897Sopenharmony_ci                i += n;
1117b1994897Sopenharmony_ci
1118b1994897Sopenharmony_ci                auto name_id = File::EntityId(state.ReadULeb128());
1119b1994897Sopenharmony_ci                std::string name = utf::Mutf8AsCString(file_->GetStringData(name_id).data);
1120b1994897Sopenharmony_ci                container_.GetOrCreateStringItem(name);
1121b1994897Sopenharmony_ci
1122b1994897Sopenharmony_ci                auto type_id = File::EntityId(state.ReadULeb128());
1123b1994897Sopenharmony_ci                std::string type_name = utf::Mutf8AsCString(file_->GetStringData(type_id).data);
1124b1994897Sopenharmony_ci                if (file_->IsExternal(type_id)) {
1125b1994897Sopenharmony_ci                    container_.GetOrCreateForeignClassItem(type_name);
1126b1994897Sopenharmony_ci                } else {
1127b1994897Sopenharmony_ci                    container_.GetOrCreateClassItem(type_name);
1128b1994897Sopenharmony_ci                }
1129b1994897Sopenharmony_ci
1130b1994897Sopenharmony_ci                auto type_signature_id = File::EntityId(state.ReadULeb128());
1131b1994897Sopenharmony_ci                std::string type_signature = utf::Mutf8AsCString(file_->GetStringData(type_signature_id).data);
1132b1994897Sopenharmony_ci                container_.GetOrCreateStringItem(type_signature);
1133b1994897Sopenharmony_ci                break;
1134b1994897Sopenharmony_ci            }
1135b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::END_LOCAL:
1136b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::RESTART_LOCAL: {
1137b1994897Sopenharmony_ci                [[maybe_unused]] int32_t reg_number;
1138b1994897Sopenharmony_ci                size_t n;
1139b1994897Sopenharmony_ci                bool is_full;
1140b1994897Sopenharmony_ci                std::tie(reg_number, n, is_full) = leb128::DecodeSigned<int32_t>(&opcode_sp[i]);
1141b1994897Sopenharmony_ci                LOG_IF(!is_full, FATAL, COMMON) << "Cannot read a register number";
1142b1994897Sopenharmony_ci                i += n;
1143b1994897Sopenharmony_ci                break;
1144b1994897Sopenharmony_ci            }
1145b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::SET_FILE: {
1146b1994897Sopenharmony_ci                auto source_file_id = File::EntityId(state.ReadULeb128());
1147b1994897Sopenharmony_ci                std::string source_file = utf::Mutf8AsCString(file_->GetStringData(source_file_id).data);
1148b1994897Sopenharmony_ci                container_.GetOrCreateStringItem(source_file);
1149b1994897Sopenharmony_ci                break;
1150b1994897Sopenharmony_ci            }
1151b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::SET_SOURCE_CODE: {
1152b1994897Sopenharmony_ci                auto source_code_id = File::EntityId(state.ReadULeb128());
1153b1994897Sopenharmony_ci                std::string source_code = utf::Mutf8AsCString(file_->GetStringData(source_code_id).data);
1154b1994897Sopenharmony_ci                container_.GetOrCreateStringItem(source_code);
1155b1994897Sopenharmony_ci                break;
1156b1994897Sopenharmony_ci            }
1157b1994897Sopenharmony_ci            default: {
1158b1994897Sopenharmony_ci                break;
1159b1994897Sopenharmony_ci            }
1160b1994897Sopenharmony_ci        }
1161b1994897Sopenharmony_ci    }
1162b1994897Sopenharmony_ci}
1163b1994897Sopenharmony_ci
1164b1994897Sopenharmony_civoid FileReader::UpdateDebugInfo(DebugInfoItem *debug_info_item, File::EntityId debug_info_id)
1165b1994897Sopenharmony_ci{
1166b1994897Sopenharmony_ci    auto *lnp_item = debug_info_item->GetLineNumberProgram();
1167b1994897Sopenharmony_ci    DebugInfoDataAccessor debug_acc(*file_, debug_info_id);
1168b1994897Sopenharmony_ci    const uint8_t *program = debug_acc.GetLineNumberProgram();
1169b1994897Sopenharmony_ci    auto size = file_->GetSpanFromId(file_->GetIdFromPointer(program)).size();
1170b1994897Sopenharmony_ci    auto opcode_sp = Span(program, size);
1171b1994897Sopenharmony_ci
1172b1994897Sopenharmony_ci    size_t i = 0;
1173b1994897Sopenharmony_ci    LineNumberProgramItem::Opcode opcode;
1174b1994897Sopenharmony_ci    panda_file::LineProgramState state(*file_, File::EntityId(0), debug_acc.GetLineStart(),
1175b1994897Sopenharmony_ci                                       debug_acc.GetConstantPool());
1176b1994897Sopenharmony_ci    while ((opcode = LineNumberProgramItem::Opcode(opcode_sp[i++])) != LineNumberProgramItem::Opcode::END_SEQUENCE) {
1177b1994897Sopenharmony_ci        switch (opcode) {
1178b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::ADVANCE_PC: {
1179b1994897Sopenharmony_ci                lnp_item->EmitAdvancePc(debug_info_item->GetConstantPool(), state.ReadULeb128());
1180b1994897Sopenharmony_ci                break;
1181b1994897Sopenharmony_ci            }
1182b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::ADVANCE_LINE: {
1183b1994897Sopenharmony_ci                lnp_item->EmitAdvanceLine(debug_info_item->GetConstantPool(), state.ReadSLeb128());
1184b1994897Sopenharmony_ci                break;
1185b1994897Sopenharmony_ci            }
1186b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::START_LOCAL: {
1187b1994897Sopenharmony_ci                auto [reg_number, n, is_full] = leb128::DecodeSigned<int32_t>(&opcode_sp[i]);
1188b1994897Sopenharmony_ci                LOG_IF(!is_full, FATAL, COMMON) << "Cannot read a register number";
1189b1994897Sopenharmony_ci                i += n;
1190b1994897Sopenharmony_ci
1191b1994897Sopenharmony_ci                auto name_id = File::EntityId(state.ReadULeb128());
1192b1994897Sopenharmony_ci                std::string name = utf::Mutf8AsCString(file_->GetStringData(name_id).data);
1193b1994897Sopenharmony_ci                auto *name_item = container_.GetOrCreateStringItem(name);
1194b1994897Sopenharmony_ci
1195b1994897Sopenharmony_ci                auto type_id = File::EntityId(state.ReadULeb128());
1196b1994897Sopenharmony_ci                std::string type_name = utf::Mutf8AsCString(file_->GetStringData(type_id).data);
1197b1994897Sopenharmony_ci                auto *type_item = file_->IsExternal(type_id)
1198b1994897Sopenharmony_ci                                      ? static_cast<BaseClassItem *>(container_.GetOrCreateForeignClassItem(type_name))
1199b1994897Sopenharmony_ci                                      : static_cast<BaseClassItem *>(container_.GetOrCreateClassItem(type_name));
1200b1994897Sopenharmony_ci
1201b1994897Sopenharmony_ci                lnp_item->EmitStartLocal(debug_info_item->GetConstantPool(), reg_number, name_item,
1202b1994897Sopenharmony_ci                                         type_item->GetNameItem());
1203b1994897Sopenharmony_ci                break;
1204b1994897Sopenharmony_ci            }
1205b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::START_LOCAL_EXTENDED: {
1206b1994897Sopenharmony_ci                auto [reg_number, n, is_full] = leb128::DecodeSigned<int32_t>(&opcode_sp[i]);
1207b1994897Sopenharmony_ci                LOG_IF(!is_full, FATAL, COMMON) << "Cannot read a register number";
1208b1994897Sopenharmony_ci                i += n;
1209b1994897Sopenharmony_ci
1210b1994897Sopenharmony_ci                auto name_id = File::EntityId(state.ReadULeb128());
1211b1994897Sopenharmony_ci                std::string name = utf::Mutf8AsCString(file_->GetStringData(name_id).data);
1212b1994897Sopenharmony_ci                auto *name_item = container_.GetOrCreateStringItem(name);
1213b1994897Sopenharmony_ci
1214b1994897Sopenharmony_ci                auto type_id = File::EntityId(state.ReadULeb128());
1215b1994897Sopenharmony_ci                std::string type_name = utf::Mutf8AsCString(file_->GetStringData(type_id).data);
1216b1994897Sopenharmony_ci                auto *type_item = file_->IsExternal(type_id)
1217b1994897Sopenharmony_ci                                      ? static_cast<BaseClassItem *>(container_.GetOrCreateForeignClassItem(type_name))
1218b1994897Sopenharmony_ci                                      : static_cast<BaseClassItem *>(container_.GetOrCreateClassItem(type_name));
1219b1994897Sopenharmony_ci
1220b1994897Sopenharmony_ci                auto type_signature_id = File::EntityId(state.ReadULeb128());
1221b1994897Sopenharmony_ci                std::string type_signature = utf::Mutf8AsCString(file_->GetStringData(type_signature_id).data);
1222b1994897Sopenharmony_ci                auto *type_signature_item = container_.GetOrCreateStringItem(type_signature);
1223b1994897Sopenharmony_ci
1224b1994897Sopenharmony_ci                lnp_item->EmitStartLocalExtended(debug_info_item->GetConstantPool(), reg_number, name_item,
1225b1994897Sopenharmony_ci                                                 type_item->GetNameItem(), type_signature_item);
1226b1994897Sopenharmony_ci                break;
1227b1994897Sopenharmony_ci            }
1228b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::END_LOCAL: {
1229b1994897Sopenharmony_ci                auto [reg_number, n, is_full] = leb128::DecodeSigned<int32_t>(&opcode_sp[i]);
1230b1994897Sopenharmony_ci                LOG_IF(!is_full, FATAL, COMMON) << "Cannot read a register number";
1231b1994897Sopenharmony_ci                i += n;
1232b1994897Sopenharmony_ci
1233b1994897Sopenharmony_ci                lnp_item->EmitEndLocal(reg_number);
1234b1994897Sopenharmony_ci                break;
1235b1994897Sopenharmony_ci            }
1236b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::RESTART_LOCAL: {
1237b1994897Sopenharmony_ci                auto [reg_number, n, is_full] = leb128::DecodeSigned<int32_t>(&opcode_sp[i]);
1238b1994897Sopenharmony_ci                LOG_IF(!is_full, FATAL, COMMON) << "Cannot read a register number";
1239b1994897Sopenharmony_ci                i += n;
1240b1994897Sopenharmony_ci
1241b1994897Sopenharmony_ci                lnp_item->EmitRestartLocal(reg_number);
1242b1994897Sopenharmony_ci                break;
1243b1994897Sopenharmony_ci            }
1244b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::SET_PROLOGUE_END: {
1245b1994897Sopenharmony_ci                lnp_item->EmitPrologEnd();
1246b1994897Sopenharmony_ci                break;
1247b1994897Sopenharmony_ci            }
1248b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::SET_EPILOGUE_BEGIN: {
1249b1994897Sopenharmony_ci                lnp_item->EmitEpilogBegin();
1250b1994897Sopenharmony_ci                break;
1251b1994897Sopenharmony_ci            }
1252b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::SET_FILE: {
1253b1994897Sopenharmony_ci                auto source_file_id = File::EntityId(state.ReadULeb128());
1254b1994897Sopenharmony_ci                std::string source_file = utf::Mutf8AsCString(file_->GetStringData(source_file_id).data);
1255b1994897Sopenharmony_ci                auto *source_file_item = container_.GetOrCreateStringItem(source_file);
1256b1994897Sopenharmony_ci                lnp_item->EmitSetFile(debug_info_item->GetConstantPool(), source_file_item);
1257b1994897Sopenharmony_ci                break;
1258b1994897Sopenharmony_ci            }
1259b1994897Sopenharmony_ci            case LineNumberProgramItem::Opcode::SET_SOURCE_CODE: {
1260b1994897Sopenharmony_ci                auto source_code_id = File::EntityId(state.ReadULeb128());
1261b1994897Sopenharmony_ci                std::string source_code = utf::Mutf8AsCString(file_->GetStringData(source_code_id).data);
1262b1994897Sopenharmony_ci                auto *source_code_item = container_.GetOrCreateStringItem(source_code);
1263b1994897Sopenharmony_ci                lnp_item->EmitSetFile(debug_info_item->GetConstantPool(), source_code_item);
1264b1994897Sopenharmony_ci                break;
1265b1994897Sopenharmony_ci            }
1266b1994897Sopenharmony_ci            default: {
1267b1994897Sopenharmony_ci                auto opcode_value = static_cast<uint8_t>(opcode);
1268b1994897Sopenharmony_ci                auto adjust_opcode = opcode_value - LineNumberProgramItem::OPCODE_BASE;
1269b1994897Sopenharmony_ci                uint32_t pc_diff = adjust_opcode / LineNumberProgramItem::LINE_RANGE;
1270b1994897Sopenharmony_ci                int32_t line_diff =
1271b1994897Sopenharmony_ci                    adjust_opcode % LineNumberProgramItem::LINE_RANGE + LineNumberProgramItem::LINE_BASE;
1272b1994897Sopenharmony_ci                lnp_item->EmitSpecialOpcode(pc_diff, line_diff);
1273b1994897Sopenharmony_ci                break;
1274b1994897Sopenharmony_ci            }
1275b1994897Sopenharmony_ci        }
1276b1994897Sopenharmony_ci    }
1277b1994897Sopenharmony_ci    lnp_item->EmitEnd();
1278b1994897Sopenharmony_ci}
1279b1994897Sopenharmony_ci
1280b1994897Sopenharmony_civoid AddIndexDependencyInstFlag(CodeItem *code_item, MethodItem *method_item,
1281b1994897Sopenharmony_ci                                const std::unordered_map<File::EntityId, File::EntityId> &reverse_done)
1282b1994897Sopenharmony_ci{
1283b1994897Sopenharmony_ci    using Flags = panda::BytecodeInst<panda::BytecodeInstMode::FAST>::Flags;
1284b1994897Sopenharmony_ci
1285b1994897Sopenharmony_ci    size_t offset = 0;
1286b1994897Sopenharmony_ci    BytecodeInstruction inst(code_item->GetInstructions()->data());
1287b1994897Sopenharmony_ci    while (offset < code_item->GetCodeSize()) {
1288b1994897Sopenharmony_ci        if (inst.HasFlag(Flags::TYPE_ID)) {
1289b1994897Sopenharmony_ci            BytecodeId b_id = inst.GetId();
1290b1994897Sopenharmony_ci            File::Index idx = b_id.AsIndex();
1291b1994897Sopenharmony_ci            File::EntityId method_id = reverse_done.find(method_item)->second;
1292b1994897Sopenharmony_ci            File::EntityId old_id = file_->ResolveClassIndex(method_id, idx);
1293b1994897Sopenharmony_ci            ASSERT(items_done_.find(old_id) != items_done_.end());
1294b1994897Sopenharmony_ci            auto *idx_item = static_cast<IndexedItem *>(items_done_.find(old_id)->second);
1295b1994897Sopenharmony_ci            method_item->AddIndexDependency(idx_item);
1296b1994897Sopenharmony_ci        } else if (inst.HasFlag(Flags::METHOD_ID)) {
1297b1994897Sopenharmony_ci            BytecodeId b_id = inst.GetId();
1298b1994897Sopenharmony_ci            File::Index idx = b_id.AsIndex();
1299b1994897Sopenharmony_ci            File::EntityId method_id = reverse_done.find(method_item)->second;
1300b1994897Sopenharmony_ci            File::EntityId old_id = file_->ResolveMethodIndex(method_id, idx);
1301b1994897Sopenharmony_ci            ASSERT(items_done_.find(old_id) != items_done_.end());
1302b1994897Sopenharmony_ci            auto *idx_item = static_cast<IndexedItem *>(items_done_.find(old_id)->second);
1303b1994897Sopenharmony_ci            method_item->AddIndexDependency(idx_item);
1304b1994897Sopenharmony_ci        } else if (inst.HasFlag(Flags::FIELD_ID)) {
1305b1994897Sopenharmony_ci            BytecodeId b_id = inst.GetId();
1306b1994897Sopenharmony_ci            File::Index idx = b_id.AsIndex();
1307b1994897Sopenharmony_ci            File::EntityId method_id = reverse_done.find(method_item)->second;
1308b1994897Sopenharmony_ci            File::EntityId old_id = file_->ResolveFieldIndex(method_id, idx);
1309b1994897Sopenharmony_ci            ASSERT(items_done_.find(old_id) != items_done_.end());
1310b1994897Sopenharmony_ci            auto *idx_item = static_cast<IndexedItem *>(items_done_.find(old_id)->second);
1311b1994897Sopenharmony_ci            method_item->AddIndexDependency(idx_item);
1312b1994897Sopenharmony_ci        } else if (inst.HasFlag(Flags::STRING_ID)) {
1313b1994897Sopenharmony_ci            BytecodeId b_id = inst.GetId();
1314b1994897Sopenharmony_ci            File::EntityId old_id = b_id.AsFileId();
1315b1994897Sopenharmony_ci            auto data = file_->GetStringData(old_id);
1316b1994897Sopenharmony_ci            std::string item_str(utf::Mutf8AsCString(data.data));
1317b1994897Sopenharmony_ci            container_.GetOrCreateStringItem(item_str);
1318b1994897Sopenharmony_ci        }
1319b1994897Sopenharmony_ci        offset += inst.GetSize();
1320b1994897Sopenharmony_ci        inst = inst.GetNext();
1321b1994897Sopenharmony_ci    }
1322b1994897Sopenharmony_ci}
1323b1994897Sopenharmony_ci
1324b1994897Sopenharmony_civoid FileReader::UpdateCodeAndDebugInfoDependencies(const std::map<BaseItem *, File::EntityId> &reverse_done)
1325b1994897Sopenharmony_ci{
1326b1994897Sopenharmony_ci    auto *class_map = container_.GetClassMap();
1327b1994897Sopenharmony_ci
1328b1994897Sopenharmony_ci    // First pass, add dependencies bytecode -> new items
1329b1994897Sopenharmony_ci    for (const auto &it : *class_map) {
1330b1994897Sopenharmony_ci        auto *base_class_item = it.second;
1331b1994897Sopenharmony_ci        if (base_class_item->IsForeign()) {
1332b1994897Sopenharmony_ci            continue;
1333b1994897Sopenharmony_ci        }
1334b1994897Sopenharmony_ci        auto *class_item = static_cast<ClassItem *>(base_class_item);
1335b1994897Sopenharmony_ci        class_item->VisitMethods([this, &reverse_done](BaseItem *param_item) {
1336b1994897Sopenharmony_ci            auto *method_item = static_cast<MethodItem *>(param_item);
1337b1994897Sopenharmony_ci            auto *code_item = method_item->GetCode();
1338b1994897Sopenharmony_ci            if (code_item == nullptr) {
1339b1994897Sopenharmony_ci                return true;
1340b1994897Sopenharmony_ci            }
1341b1994897Sopenharmony_ci
1342b1994897Sopenharmony_ci            auto *debug_info_item = method_item->GetDebugInfo();
1343b1994897Sopenharmony_ci            if (debug_info_item != nullptr) {
1344b1994897Sopenharmony_ci                UpdateDebugInfoDependecies(reverse_done.find(debug_info_item)->second);
1345b1994897Sopenharmony_ci            }
1346b1994897Sopenharmony_ci
1347b1994897Sopenharmony_ci            AddIndexDependencyInstFlag(inst, method_item, reverse_done);
1348b1994897Sopenharmony_ci
1349b1994897Sopenharmony_ci            return true;
1350b1994897Sopenharmony_ci        });
1351b1994897Sopenharmony_ci    }
1352b1994897Sopenharmony_ci}
1353b1994897Sopenharmony_ci
1354b1994897Sopenharmony_civoid UpdateIdInstFlag(CodeItem *code_item, MethodItem *method_item,
1355b1994897Sopenharmony_ci                      const std::unordered_map<File::EntityId, File::EntityId> &reverse_done)
1356b1994897Sopenharmony_ci{
1357b1994897Sopenharmony_ci    using Flags = panda::BytecodeInst<panda::BytecodeInstMode::FAST>::Flags;
1358b1994897Sopenharmony_ci
1359b1994897Sopenharmony_ci    size_t offset = 0;
1360b1994897Sopenharmony_ci    BytecodeInstruction inst(code_item->GetInstructions()->data());
1361b1994897Sopenharmony_ci    while (offset < code_item->GetCodeSize()) {
1362b1994897Sopenharmony_ci        if (inst.HasFlag(Flags::TYPE_ID)) {
1363b1994897Sopenharmony_ci            BytecodeId b_id = inst.GetId();
1364b1994897Sopenharmony_ci            File::Index idx = b_id.AsIndex();
1365b1994897Sopenharmony_ci            File::EntityId method_id = reverse_done.find(method_item)->second;
1366b1994897Sopenharmony_ci            File::EntityId old_id = file_->ResolveClassIndex(method_id, idx);
1367b1994897Sopenharmony_ci            ASSERT(items_done_.find(old_id) != items_done_.end());
1368b1994897Sopenharmony_ci            auto *idx_item = static_cast<IndexedItem *>(items_done_.find(old_id)->second);
1369b1994897Sopenharmony_ci            uint32_t index = idx_item->GetIndex(method_item);
1370b1994897Sopenharmony_ci            inst.UpdateId(BytecodeId(index));
1371b1994897Sopenharmony_ci        } else if (inst.HasFlag(Flags::METHOD_ID)) {
1372b1994897Sopenharmony_ci            BytecodeId b_id = inst.GetId();
1373b1994897Sopenharmony_ci            File::Index idx = b_id.AsIndex();
1374b1994897Sopenharmony_ci            File::EntityId method_id = reverse_done.find(method_item)->second;
1375b1994897Sopenharmony_ci            File::EntityId old_id = file_->ResolveMethodIndex(method_id, idx);
1376b1994897Sopenharmony_ci            ASSERT(items_done_.find(old_id) != items_done_.end());
1377b1994897Sopenharmony_ci            auto *idx_item = static_cast<IndexedItem *>(items_done_.find(old_id)->second);
1378b1994897Sopenharmony_ci            uint32_t index = idx_item->GetIndex(method_item);
1379b1994897Sopenharmony_ci            inst.UpdateId(BytecodeId(index));
1380b1994897Sopenharmony_ci        } else if (inst.HasFlag(Flags::FIELD_ID)) {
1381b1994897Sopenharmony_ci            BytecodeId b_id = inst.GetId();
1382b1994897Sopenharmony_ci            File::Index idx = b_id.AsIndex();
1383b1994897Sopenharmony_ci            File::EntityId method_id = reverse_done.find(method_item)->second;
1384b1994897Sopenharmony_ci            File::EntityId old_id = file_->ResolveFieldIndex(method_id, idx);
1385b1994897Sopenharmony_ci            ASSERT(items_done_.find(old_id) != items_done_.end());
1386b1994897Sopenharmony_ci            auto *idx_item = static_cast<IndexedItem *>(items_done_.find(old_id)->second);
1387b1994897Sopenharmony_ci            uint32_t index = idx_item->GetIndex(method_item);
1388b1994897Sopenharmony_ci            inst.UpdateId(BytecodeId(index));
1389b1994897Sopenharmony_ci        } else if (inst.HasFlag(Flags::STRING_ID)) {
1390b1994897Sopenharmony_ci            BytecodeId b_id = inst.GetId();
1391b1994897Sopenharmony_ci            File::EntityId old_id = b_id.AsFileId();
1392b1994897Sopenharmony_ci            auto data = file_->GetStringData(old_id);
1393b1994897Sopenharmony_ci            std::string item_str(utf::Mutf8AsCString(data.data));
1394b1994897Sopenharmony_ci            auto *string_item = container_.GetOrCreateStringItem(item_str);
1395b1994897Sopenharmony_ci            inst.UpdateId(BytecodeId(string_item->GetFileId().GetOffset()));
1396b1994897Sopenharmony_ci        } else if (inst.HasFlag(Flags::LITERALARRAY_ID)) {
1397b1994897Sopenharmony_ci            BytecodeId b_id = inst.GetId();
1398b1994897Sopenharmony_ci            File::EntityId old_id = b_id.AsFileId();
1399b1994897Sopenharmony_ci            ASSERT(items_done_.find(old_id) != items_done_.end());
1400b1994897Sopenharmony_ci            auto *array_item = items_done_.find(old_id)->second;
1401b1994897Sopenharmony_ci            inst.UpdateId(BytecodeId(array_item->GetFileId().GetOffset()));
1402b1994897Sopenharmony_ci        }
1403b1994897Sopenharmony_ci        offset += inst.GetSize();
1404b1994897Sopenharmony_ci        inst = inst.GetNext();
1405b1994897Sopenharmony_ci    }
1406b1994897Sopenharmony_ci}
1407b1994897Sopenharmony_ci
1408b1994897Sopenharmony_civoid FileReader::ComputeLayoutAndUpdateIndices()
1409b1994897Sopenharmony_ci{
1410b1994897Sopenharmony_ci    std::map<BaseItem *, File::EntityId> reverse_done;
1411b1994897Sopenharmony_ci    for (const auto &it : items_done_) {
1412b1994897Sopenharmony_ci        reverse_done.insert({it.second, it.first});
1413b1994897Sopenharmony_ci    }
1414b1994897Sopenharmony_ci
1415b1994897Sopenharmony_ci    auto *class_map = container_.GetClassMap();
1416b1994897Sopenharmony_ci
1417b1994897Sopenharmony_ci    UpdateCodeAndDebugInfoDependencies(reverse_done);
1418b1994897Sopenharmony_ci
1419b1994897Sopenharmony_ci    container_.ComputeLayout();
1420b1994897Sopenharmony_ci
1421b1994897Sopenharmony_ci    // Second pass, update debug info
1422b1994897Sopenharmony_ci    for (const auto &it : *class_map) {
1423b1994897Sopenharmony_ci        auto *base_class_item = it.second;
1424b1994897Sopenharmony_ci        if (base_class_item->IsForeign()) {
1425b1994897Sopenharmony_ci            continue;
1426b1994897Sopenharmony_ci        }
1427b1994897Sopenharmony_ci        auto *class_item = static_cast<ClassItem *>(base_class_item);
1428b1994897Sopenharmony_ci        class_item->VisitMethods([this, &reverse_done](BaseItem *param_item) {
1429b1994897Sopenharmony_ci            auto *method_item = static_cast<MethodItem *>(param_item);
1430b1994897Sopenharmony_ci            auto *code_item = method_item->GetCode();
1431b1994897Sopenharmony_ci            if (code_item == nullptr) {
1432b1994897Sopenharmony_ci                return true;
1433b1994897Sopenharmony_ci            }
1434b1994897Sopenharmony_ci
1435b1994897Sopenharmony_ci            auto *debug_info_item = method_item->GetDebugInfo();
1436b1994897Sopenharmony_ci            if (debug_info_item != nullptr) {
1437b1994897Sopenharmony_ci                UpdateDebugInfo(debug_info_item, reverse_done.find(debug_info_item)->second);
1438b1994897Sopenharmony_ci            }
1439b1994897Sopenharmony_ci
1440b1994897Sopenharmony_ci            return true;
1441b1994897Sopenharmony_ci        });
1442b1994897Sopenharmony_ci    }
1443b1994897Sopenharmony_ci
1444b1994897Sopenharmony_ci    container_.DeduplicateItems(false);
1445b1994897Sopenharmony_ci    container_.ComputeLayout();
1446b1994897Sopenharmony_ci
1447b1994897Sopenharmony_ci    // Third pass, update bytecode indices
1448b1994897Sopenharmony_ci    for (const auto &it : *class_map) {
1449b1994897Sopenharmony_ci        auto *base_class_item = it.second;
1450b1994897Sopenharmony_ci        if (base_class_item->IsForeign()) {
1451b1994897Sopenharmony_ci            continue;
1452b1994897Sopenharmony_ci        }
1453b1994897Sopenharmony_ci        auto *class_item = static_cast<ClassItem *>(base_class_item);
1454b1994897Sopenharmony_ci        class_item->VisitMethods([this, &reverse_done](BaseItem *param_item) {
1455b1994897Sopenharmony_ci            auto *method_item = static_cast<MethodItem *>(param_item);
1456b1994897Sopenharmony_ci            auto *code_item = method_item->GetCode();
1457b1994897Sopenharmony_ci            if (code_item == nullptr) {
1458b1994897Sopenharmony_ci                return true;
1459b1994897Sopenharmony_ci            }
1460b1994897Sopenharmony_ci
1461b1994897Sopenharmony_ci            UpdateIdInstFlag(code_item, method_item, reverse_done);
1462b1994897Sopenharmony_ci
1463b1994897Sopenharmony_ci            return true;
1464b1994897Sopenharmony_ci        });
1465b1994897Sopenharmony_ci    }
1466b1994897Sopenharmony_ci}
1467b1994897Sopenharmony_ci
1468b1994897Sopenharmony_ci}  // namespace panda::panda_file
1469