1ca0551cfSopenharmony_ci/*
2ca0551cfSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3ca0551cfSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4ca0551cfSopenharmony_ci * you may not use this file except in compliance with the License.
5ca0551cfSopenharmony_ci * You may obtain a copy of the License at
6ca0551cfSopenharmony_ci *
7ca0551cfSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8ca0551cfSopenharmony_ci *
9ca0551cfSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10ca0551cfSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11ca0551cfSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12ca0551cfSopenharmony_ci * See the License for the specific language governing permissions and
13ca0551cfSopenharmony_ci * limitations under the License.
14ca0551cfSopenharmony_ci */
15ca0551cfSopenharmony_ci
16ca0551cfSopenharmony_ci#include "metadata/metadata_builder.h"
17ca0551cfSopenharmony_ci#include <cstring>
18ca0551cfSopenharmony_ci#include "securec.h"
19ca0551cfSopenharmony_ci#include "ast/ast_array_type.h"
20ca0551cfSopenharmony_ci#include "ast/ast_list_type.h"
21ca0551cfSopenharmony_ci#include "ast/ast_map_type.h"
22ca0551cfSopenharmony_ci#include "util/logger.h"
23ca0551cfSopenharmony_ci
24ca0551cfSopenharmony_ci#define ALIGN8(v) (((v) + 7) & ~7)
25ca0551cfSopenharmony_ci
26ca0551cfSopenharmony_cinamespace OHOS {
27ca0551cfSopenharmony_cinamespace Idl {
28ca0551cfSopenharmony_ciconst char* MetadataBuilder::tag = "MetadataBuilder";
29ca0551cfSopenharmony_cistd::shared_ptr<MetaComponent> MetadataBuilder::Build()
30ca0551cfSopenharmony_ci{
31ca0551cfSopenharmony_ci    if (!module_->IsValid()) {
32ca0551cfSopenharmony_ci        Logger::E(tag, "The module is not validate.");
33ca0551cfSopenharmony_ci        return nullptr;
34ca0551cfSopenharmony_ci    }
35ca0551cfSopenharmony_ci
36ca0551cfSopenharmony_ci    size_ = CalculateMetadataSize();
37ca0551cfSopenharmony_ci    if (size_ > 0) {
38ca0551cfSopenharmony_ci        void* metadata =  calloc(size_, 1);
39ca0551cfSopenharmony_ci        if (metadata == nullptr) {
40ca0551cfSopenharmony_ci            Logger::E(tag, "Out of memory.");
41ca0551cfSopenharmony_ci            return nullptr;
42ca0551cfSopenharmony_ci        }
43ca0551cfSopenharmony_ci        metaComponent_.reset(
44ca0551cfSopenharmony_ci            new(metadata) MetaComponent, [](MetaComponent* p) { free(p); });
45ca0551cfSopenharmony_ci
46ca0551cfSopenharmony_ci        WriteMetadata(reinterpret_cast<uintptr_t>(metadata));
47ca0551cfSopenharmony_ci    } else {
48ca0551cfSopenharmony_ci        return nullptr;
49ca0551cfSopenharmony_ci    }
50ca0551cfSopenharmony_ci
51ca0551cfSopenharmony_ci    return metaComponent_;
52ca0551cfSopenharmony_ci}
53ca0551cfSopenharmony_ci
54ca0551cfSopenharmony_cisize_t MetadataBuilder::CalculateMetadataSize()
55ca0551cfSopenharmony_ci{
56ca0551cfSopenharmony_ci    baseAddr_ = 0;
57ca0551cfSopenharmony_ci    CalculateMetaComponent(module_);
58ca0551cfSopenharmony_ci    return baseAddr_;
59ca0551cfSopenharmony_ci}
60ca0551cfSopenharmony_ci
61ca0551cfSopenharmony_civoid MetadataBuilder::CalculateMetaComponent(ASTModule* module)
62ca0551cfSopenharmony_ci{
63ca0551cfSopenharmony_ci    size_t namespaceNumber = module->GetNamespaceNumber();
64ca0551cfSopenharmony_ci    size_t sequenceableNumber = module->GetSequenceableNumber();
65ca0551cfSopenharmony_ci    size_t interfaceNumber = module->GetInterfaceNumber();
66ca0551cfSopenharmony_ci    size_t typeNumber = module->GetTypeNumber();
67ca0551cfSopenharmony_ci
68ca0551cfSopenharmony_ci    // begin address
69ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_);
70ca0551cfSopenharmony_ci    // stringPool_'s address
71ca0551cfSopenharmony_ci    stringPool_.Add(module_->GetName());
72ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaComponent));
73ca0551cfSopenharmony_ci    // namespaces_'s address
74ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaNamespace*) * namespaceNumber);
75ca0551cfSopenharmony_ci    // sequenceables_'s address
76ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaSequenceable*) * sequenceableNumber);
77ca0551cfSopenharmony_ci    // interfaces_'s address
78ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaInterface*) * interfaceNumber);
79ca0551cfSopenharmony_ci    // types_'s address
80ca0551cfSopenharmony_ci    baseAddr_ = baseAddr_ + sizeof(MetaType*) * typeNumber;
81ca0551cfSopenharmony_ci
82ca0551cfSopenharmony_ci    for (size_t i = 0; i < namespaceNumber; i++) {
83ca0551cfSopenharmony_ci        CalculateMetaNamespace(module->GetNamespace(i));
84ca0551cfSopenharmony_ci    }
85ca0551cfSopenharmony_ci
86ca0551cfSopenharmony_ci    for (size_t i = 0; i < sequenceableNumber; i++) {
87ca0551cfSopenharmony_ci        CalculateMetaSequenceable(module->GetSequenceable(i));
88ca0551cfSopenharmony_ci    }
89ca0551cfSopenharmony_ci
90ca0551cfSopenharmony_ci    for (size_t i = 0; i < interfaceNumber; i++) {
91ca0551cfSopenharmony_ci        CalculateMetaInterface(module->GetInterface(i));
92ca0551cfSopenharmony_ci    }
93ca0551cfSopenharmony_ci
94ca0551cfSopenharmony_ci    const ASTModule::TypeStringMap& types = module_->GetTypes();
95ca0551cfSopenharmony_ci    for (const auto& pair : types) {
96ca0551cfSopenharmony_ci        CalculateMetaType(pair.second);
97ca0551cfSopenharmony_ci    }
98ca0551cfSopenharmony_ci
99ca0551cfSopenharmony_ci    // end address
100ca0551cfSopenharmony_ci    CalculateStringPool();
101ca0551cfSopenharmony_ci}
102ca0551cfSopenharmony_ci
103ca0551cfSopenharmony_civoid MetadataBuilder::CalculateMetaNamespace(ASTNamespace* nspace)
104ca0551cfSopenharmony_ci{
105ca0551cfSopenharmony_ci    size_t sequenceableNumber = nspace->GetSequenceableNumber();
106ca0551cfSopenharmony_ci    size_t interfaceNumber = nspace->GetInterfaceNumber();
107ca0551cfSopenharmony_ci    size_t namespaceNumber = nspace->GetNamespaceNumber();
108ca0551cfSopenharmony_ci
109ca0551cfSopenharmony_ci    // begin address
110ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_);
111ca0551cfSopenharmony_ci    stringPool_.Add(nspace->GetName());
112ca0551cfSopenharmony_ci    // sequenceables_'s address
113ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaNamespace));
114ca0551cfSopenharmony_ci    // interfaces_'s address
115ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_ + sizeof(int) * sequenceableNumber);
116ca0551cfSopenharmony_ci    // namespaces_'s address
117ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_ + sizeof(int) * interfaceNumber);
118ca0551cfSopenharmony_ci    // end address
119ca0551cfSopenharmony_ci    baseAddr_ = baseAddr_ + sizeof(MetaNamespace*) * namespaceNumber;
120ca0551cfSopenharmony_ci
121ca0551cfSopenharmony_ci    for (size_t i = 0; i < namespaceNumber; i++) {
122ca0551cfSopenharmony_ci        CalculateMetaNamespace(nspace->GetNamespace(i));
123ca0551cfSopenharmony_ci    }
124ca0551cfSopenharmony_ci}
125ca0551cfSopenharmony_ci
126ca0551cfSopenharmony_civoid MetadataBuilder::CalculateMetaSequenceable(ASTSequenceableType* sequenceable)
127ca0551cfSopenharmony_ci{
128ca0551cfSopenharmony_ci    // begin address
129ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_);
130ca0551cfSopenharmony_ci    stringPool_.Add(sequenceable->GetName());
131ca0551cfSopenharmony_ci    stringPool_.Add(sequenceable->GetNamespace()->ToString());
132ca0551cfSopenharmony_ci    // end address
133ca0551cfSopenharmony_ci    baseAddr_ = baseAddr_ + sizeof(MetaSequenceable);
134ca0551cfSopenharmony_ci}
135ca0551cfSopenharmony_ci
136ca0551cfSopenharmony_civoid MetadataBuilder::CalculateMetaInterface(ASTInterfaceType* interface)
137ca0551cfSopenharmony_ci{
138ca0551cfSopenharmony_ci    size_t methodNumber = interface->GetMethodNumber();
139ca0551cfSopenharmony_ci
140ca0551cfSopenharmony_ci    // begin address
141ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_);
142ca0551cfSopenharmony_ci    stringPool_.Add(interface->GetLicense());
143ca0551cfSopenharmony_ci    stringPool_.Add(interface->GetName());
144ca0551cfSopenharmony_ci    stringPool_.Add(interface->GetNamespace()->ToString());
145ca0551cfSopenharmony_ci    // methods_'s address
146ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaInterface));
147ca0551cfSopenharmony_ci    // end address
148ca0551cfSopenharmony_ci    baseAddr_ = baseAddr_ + sizeof(MetaMethod*) * methodNumber;
149ca0551cfSopenharmony_ci
150ca0551cfSopenharmony_ci    for (size_t i = 0; i < methodNumber; i++) {
151ca0551cfSopenharmony_ci        CalculateMetaMethod(interface->GetMethod(i));
152ca0551cfSopenharmony_ci    }
153ca0551cfSopenharmony_ci}
154ca0551cfSopenharmony_ci
155ca0551cfSopenharmony_civoid MetadataBuilder::CalculateMetaMethod(ASTMethod* method)
156ca0551cfSopenharmony_ci{
157ca0551cfSopenharmony_ci    size_t parameterNumber = method->GetParameterNumber();
158ca0551cfSopenharmony_ci
159ca0551cfSopenharmony_ci    // begin address
160ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_);
161ca0551cfSopenharmony_ci    stringPool_.Add(method->GetName());
162ca0551cfSopenharmony_ci    stringPool_.Add(method->GetSignature());
163ca0551cfSopenharmony_ci    // parameters_'s address
164ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaMethod));
165ca0551cfSopenharmony_ci    // end address
166ca0551cfSopenharmony_ci    baseAddr_ = baseAddr_ + sizeof(MetaParameter*) * parameterNumber;
167ca0551cfSopenharmony_ci
168ca0551cfSopenharmony_ci    for (size_t i = 0; i < parameterNumber; i++) {
169ca0551cfSopenharmony_ci        CalculateMetaParameter(method->GetParameter(i));
170ca0551cfSopenharmony_ci    }
171ca0551cfSopenharmony_ci}
172ca0551cfSopenharmony_ci
173ca0551cfSopenharmony_civoid MetadataBuilder::CalculateMetaParameter(ASTParameter* parameter)
174ca0551cfSopenharmony_ci{
175ca0551cfSopenharmony_ci    // begin address
176ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_);
177ca0551cfSopenharmony_ci    stringPool_.Add(parameter->GetName());
178ca0551cfSopenharmony_ci    // end address
179ca0551cfSopenharmony_ci    baseAddr_ = baseAddr_ + sizeof(MetaParameter);
180ca0551cfSopenharmony_ci}
181ca0551cfSopenharmony_ci
182ca0551cfSopenharmony_civoid MetadataBuilder::CalculateMetaType(ASTType* type)
183ca0551cfSopenharmony_ci{
184ca0551cfSopenharmony_ci    // begin address
185ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_);
186ca0551cfSopenharmony_ci    // nestedTypeIndexes_'s address
187ca0551cfSopenharmony_ci    baseAddr_ = baseAddr_ + sizeof(MetaType);
188ca0551cfSopenharmony_ci    if (type->IsListType()) {
189ca0551cfSopenharmony_ci        baseAddr_ = ALIGN8(baseAddr_);
190ca0551cfSopenharmony_ci        // end address
191ca0551cfSopenharmony_ci        baseAddr_ = baseAddr_ + sizeof(int*);
192ca0551cfSopenharmony_ci    } else if (type->IsMapType()) {
193ca0551cfSopenharmony_ci        // end address
194ca0551cfSopenharmony_ci        size_t typeNumber = 2;
195ca0551cfSopenharmony_ci        baseAddr_ = baseAddr_ + sizeof(int*) * typeNumber;
196ca0551cfSopenharmony_ci    } else if (type->IsArrayType()) {
197ca0551cfSopenharmony_ci        baseAddr_ = baseAddr_ + sizeof(int*);
198ca0551cfSopenharmony_ci    }
199ca0551cfSopenharmony_ci}
200ca0551cfSopenharmony_ci
201ca0551cfSopenharmony_civoid MetadataBuilder::CalculateStringPool()
202ca0551cfSopenharmony_ci{
203ca0551cfSopenharmony_ci    // begin address
204ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_);
205ca0551cfSopenharmony_ci    // end address
206ca0551cfSopenharmony_ci    baseAddr_ = baseAddr_ + stringPool_.GetSize();
207ca0551cfSopenharmony_ci}
208ca0551cfSopenharmony_ci
209ca0551cfSopenharmony_civoid MetadataBuilder::WriteMetadata(uintptr_t base)
210ca0551cfSopenharmony_ci{
211ca0551cfSopenharmony_ci    baseAddr_ = base;
212ca0551cfSopenharmony_ci    WriteMetaComponent(module_);
213ca0551cfSopenharmony_ci}
214ca0551cfSopenharmony_ci
215ca0551cfSopenharmony_civoid MetadataBuilder::WriteMetaComponent(ASTModule* module)
216ca0551cfSopenharmony_ci{
217ca0551cfSopenharmony_ci    size_t namespaceNumber = module->GetNamespaceNumber();
218ca0551cfSopenharmony_ci    size_t sequenceableNumber = module->GetSequenceableNumber();
219ca0551cfSopenharmony_ci    size_t interfaceNumber = module->GetInterfaceNumber();
220ca0551cfSopenharmony_ci    size_t typeNumber = module->GetTypeNumber();
221ca0551cfSopenharmony_ci    bool hasCacheableProxyMethods = module->GetHasCacheableProxyMethods();
222ca0551cfSopenharmony_ci
223ca0551cfSopenharmony_ci    // begin address
224ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_);
225ca0551cfSopenharmony_ci    MetaComponent* mc = reinterpret_cast<MetaComponent*>(baseAddr_);
226ca0551cfSopenharmony_ci    mc->magic_ = METADATA_MAGIC_NUMBER;
227ca0551cfSopenharmony_ci    mc->size_ = static_cast<int>(size_);
228ca0551cfSopenharmony_ci    mc->namespaceNumber_ = static_cast<int>(namespaceNumber);
229ca0551cfSopenharmony_ci    mc->sequenceableNumber_ = static_cast<int>(sequenceableNumber);
230ca0551cfSopenharmony_ci    mc->interfaceNumber_ = static_cast<int>(interfaceNumber);
231ca0551cfSopenharmony_ci    mc->typeNumber_ = static_cast<int>(typeNumber);
232ca0551cfSopenharmony_ci    mc->hasCacheableProxyMethods_ = hasCacheableProxyMethods;
233ca0551cfSopenharmony_ci    mc->stringPoolSize_ = stringPool_.GetSize();
234ca0551cfSopenharmony_ci    // namespaces_'s address
235ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaComponent));
236ca0551cfSopenharmony_ci    mc->namespaces_ = reinterpret_cast<MetaNamespace**>(baseAddr_);
237ca0551cfSopenharmony_ci    // sequenceables_'s address
238ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaNamespace*) * namespaceNumber);
239ca0551cfSopenharmony_ci    mc->sequenceables_ = reinterpret_cast<MetaSequenceable**>(baseAddr_);
240ca0551cfSopenharmony_ci    // interfaces_'s address
241ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaSequenceable*) * sequenceableNumber);
242ca0551cfSopenharmony_ci    mc->interfaces_ = reinterpret_cast<MetaInterface**>(baseAddr_);
243ca0551cfSopenharmony_ci    // types_'s address
244ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaInterface*) * interfaceNumber);
245ca0551cfSopenharmony_ci    mc->types_ = reinterpret_cast<MetaType**>(baseAddr_);
246ca0551cfSopenharmony_ci    // stringPool_'s address
247ca0551cfSopenharmony_ci    baseAddr_ = baseAddr_ + sizeof(MetaType*) * typeNumber;
248ca0551cfSopenharmony_ci    mc->stringPool_ = reinterpret_cast<char*>(baseAddr_);
249ca0551cfSopenharmony_ci    // end address
250ca0551cfSopenharmony_ci    baseAddr_ = baseAddr_ + stringPool_.GetSize();
251ca0551cfSopenharmony_ci    (void)memcpy_s(mc->stringPool_, stringPool_.GetSize(), stringPool_.GetData(), stringPool_.GetSize());
252ca0551cfSopenharmony_ci
253ca0551cfSopenharmony_ci    mc->name_ = WriteString(module->GetName());
254ca0551cfSopenharmony_ci
255ca0551cfSopenharmony_ci    for (size_t i = 0; i < namespaceNumber; i++) {
256ca0551cfSopenharmony_ci        mc->namespaces_[i] = WriteMetaNamespace(module->GetNamespace(i));
257ca0551cfSopenharmony_ci    }
258ca0551cfSopenharmony_ci
259ca0551cfSopenharmony_ci    for (size_t i = 0; i < sequenceableNumber; i++) {
260ca0551cfSopenharmony_ci        mc->sequenceables_[i] = WriteMetaSequenceable(module->GetSequenceable(i));
261ca0551cfSopenharmony_ci    }
262ca0551cfSopenharmony_ci
263ca0551cfSopenharmony_ci    for (size_t i = 0; i < interfaceNumber; i++) {
264ca0551cfSopenharmony_ci        mc->interfaces_[i] = WriteMetaInterface(module->GetInterface(i));
265ca0551cfSopenharmony_ci    }
266ca0551cfSopenharmony_ci
267ca0551cfSopenharmony_ci    const ASTModule::TypeStringMap& types = module->GetTypes();
268ca0551cfSopenharmony_ci    int i = 0;
269ca0551cfSopenharmony_ci    for (const auto& pair : types) {
270ca0551cfSopenharmony_ci        mc->types_[i++] = WriteMetaType(pair.second);
271ca0551cfSopenharmony_ci    }
272ca0551cfSopenharmony_ci}
273ca0551cfSopenharmony_ci
274ca0551cfSopenharmony_ciMetaNamespace* MetadataBuilder::WriteMetaNamespace(ASTNamespace* nspace)
275ca0551cfSopenharmony_ci{
276ca0551cfSopenharmony_ci    size_t sequenceableNumber = nspace->GetSequenceableNumber();
277ca0551cfSopenharmony_ci    size_t interfaceNumber = nspace->GetInterfaceNumber();
278ca0551cfSopenharmony_ci    size_t namespaceNumber = nspace->GetNamespaceNumber();
279ca0551cfSopenharmony_ci
280ca0551cfSopenharmony_ci    // begin address
281ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_);
282ca0551cfSopenharmony_ci    MetaNamespace* mn = reinterpret_cast<MetaNamespace*>(baseAddr_);
283ca0551cfSopenharmony_ci    mn->name_ = WriteString(nspace->GetName());
284ca0551cfSopenharmony_ci    mn->sequenceableNumber_ = static_cast<int>(sequenceableNumber);
285ca0551cfSopenharmony_ci    mn->interfaceNumber_ = static_cast<int>(interfaceNumber);
286ca0551cfSopenharmony_ci    mn->namespaceNumber_ = static_cast<int>(namespaceNumber);
287ca0551cfSopenharmony_ci    // sequenceables_'s address
288ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaNamespace));
289ca0551cfSopenharmony_ci    mn->sequenceableIndexes_ = reinterpret_cast<int*>(baseAddr_);
290ca0551cfSopenharmony_ci    // interfaces_'s address
291ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_ + sizeof(int) * sequenceableNumber);
292ca0551cfSopenharmony_ci    mn->interfaceIndexes_ = reinterpret_cast<int*>(baseAddr_);
293ca0551cfSopenharmony_ci    // namespaces_'s address
294ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_ + sizeof(int) * interfaceNumber);
295ca0551cfSopenharmony_ci    mn->namespaces_ = reinterpret_cast<MetaNamespace**>(baseAddr_);
296ca0551cfSopenharmony_ci    // end address
297ca0551cfSopenharmony_ci    baseAddr_ = baseAddr_ + sizeof(MetaNamespace*) * namespaceNumber;
298ca0551cfSopenharmony_ci
299ca0551cfSopenharmony_ci    for (size_t i = 0; i < sequenceableNumber; i++) {
300ca0551cfSopenharmony_ci        AutoPtr<ASTSequenceableType> sequenceable = nspace->GetSequenceable(i);
301ca0551cfSopenharmony_ci        mn->sequenceableIndexes_[i] = module_->IndexOf(sequenceable);
302ca0551cfSopenharmony_ci    }
303ca0551cfSopenharmony_ci
304ca0551cfSopenharmony_ci    for (size_t i = 0; i < interfaceNumber; i++) {
305ca0551cfSopenharmony_ci        AutoPtr<ASTInterfaceType> interface = nspace->GetInterface(i);
306ca0551cfSopenharmony_ci        mn->interfaceIndexes_[i] = module_->IndexOf(interface);
307ca0551cfSopenharmony_ci    }
308ca0551cfSopenharmony_ci
309ca0551cfSopenharmony_ci    for (size_t i = 0; i < namespaceNumber; i++) {
310ca0551cfSopenharmony_ci        AutoPtr<ASTNamespace> inner = nspace->GetNamespace(i);
311ca0551cfSopenharmony_ci        mn->namespaces_[i] = WriteMetaNamespace(inner);
312ca0551cfSopenharmony_ci    }
313ca0551cfSopenharmony_ci
314ca0551cfSopenharmony_ci    return mn;
315ca0551cfSopenharmony_ci}
316ca0551cfSopenharmony_ci
317ca0551cfSopenharmony_ciMetaSequenceable* MetadataBuilder::WriteMetaSequenceable(ASTSequenceableType* parcelabe)
318ca0551cfSopenharmony_ci{
319ca0551cfSopenharmony_ci    // begin address
320ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_);
321ca0551cfSopenharmony_ci    MetaSequenceable* mp = reinterpret_cast<MetaSequenceable*>(baseAddr_);
322ca0551cfSopenharmony_ci    mp->name_ = WriteString(parcelabe->GetName());
323ca0551cfSopenharmony_ci    mp->namespace_ = WriteString(parcelabe->GetNamespace()->ToString());
324ca0551cfSopenharmony_ci    // end address
325ca0551cfSopenharmony_ci    baseAddr_ = baseAddr_ + sizeof(MetaSequenceable);
326ca0551cfSopenharmony_ci
327ca0551cfSopenharmony_ci    return mp;
328ca0551cfSopenharmony_ci}
329ca0551cfSopenharmony_ci
330ca0551cfSopenharmony_ciMetaInterface* MetadataBuilder::WriteMetaInterface(ASTInterfaceType* interface)
331ca0551cfSopenharmony_ci{
332ca0551cfSopenharmony_ci    size_t methodNumber = interface->GetMethodNumber();
333ca0551cfSopenharmony_ci
334ca0551cfSopenharmony_ci    // begin address
335ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_);
336ca0551cfSopenharmony_ci    MetaInterface* mi = reinterpret_cast<MetaInterface*>(baseAddr_);
337ca0551cfSopenharmony_ci    mi->license_ = WriteString(interface->GetLicense());
338ca0551cfSopenharmony_ci    mi->name_ = WriteString(interface->GetName());
339ca0551cfSopenharmony_ci    mi->namespace_ = WriteString(interface->GetNamespace()->ToString());
340ca0551cfSopenharmony_ci    mi->properties_ = interface->IsOneway() ? INTERFACE_PROPERTY_ONEWAY : 0;
341ca0551cfSopenharmony_ci    mi->methodNumber_ = static_cast<int>(methodNumber);
342ca0551cfSopenharmony_ci    mi->external_ = interface->IsExternal();
343ca0551cfSopenharmony_ci    // methods_'s address
344ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaInterface));
345ca0551cfSopenharmony_ci    mi->methods_ = reinterpret_cast<MetaMethod**>(baseAddr_);
346ca0551cfSopenharmony_ci    // end address
347ca0551cfSopenharmony_ci    baseAddr_ = baseAddr_ + sizeof(MetaMethod*) * methodNumber;
348ca0551cfSopenharmony_ci
349ca0551cfSopenharmony_ci    for (size_t i = 0; i < methodNumber; i++) {
350ca0551cfSopenharmony_ci        mi->methods_[i] = WriteMetaMethod(interface->GetMethod(i));
351ca0551cfSopenharmony_ci    }
352ca0551cfSopenharmony_ci
353ca0551cfSopenharmony_ci    return mi;
354ca0551cfSopenharmony_ci}
355ca0551cfSopenharmony_ci
356ca0551cfSopenharmony_ciMetaMethod* MetadataBuilder::WriteMetaMethod(ASTMethod* method)
357ca0551cfSopenharmony_ci{
358ca0551cfSopenharmony_ci    size_t parameterNumber = method->GetParameterNumber();
359ca0551cfSopenharmony_ci
360ca0551cfSopenharmony_ci    // begin address
361ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_);
362ca0551cfSopenharmony_ci    MetaMethod* mm = reinterpret_cast<MetaMethod*>(baseAddr_);
363ca0551cfSopenharmony_ci    mm->name_ = WriteString(method->GetName());
364ca0551cfSopenharmony_ci    mm->signature_ = WriteString(method->GetSignature());
365ca0551cfSopenharmony_ci    mm->properties_ = method->IsOneway() ? METHOD_PROPERTY_ONEWAY : 0;
366ca0551cfSopenharmony_ci    mm->returnTypeIndex_ = module_->IndexOf(method->GetReturnType());
367ca0551cfSopenharmony_ci    // cacheable time
368ca0551cfSopenharmony_ci    mm->cacheable_ = method->GetCacheable();
369ca0551cfSopenharmony_ci    if (mm->cacheable_ == true) {
370ca0551cfSopenharmony_ci        mm->cacheabletime_ = method->GetCacheableTime();
371ca0551cfSopenharmony_ci    }
372ca0551cfSopenharmony_ci    mm->parameterNumber_ = static_cast<int>(parameterNumber);
373ca0551cfSopenharmony_ci    // parameters_'s address
374ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_ + sizeof(MetaMethod));
375ca0551cfSopenharmony_ci    mm->parameters_ = reinterpret_cast<MetaParameter**>(baseAddr_);
376ca0551cfSopenharmony_ci    // end address
377ca0551cfSopenharmony_ci    baseAddr_ = baseAddr_ + sizeof(MetaParameter*) * parameterNumber;
378ca0551cfSopenharmony_ci
379ca0551cfSopenharmony_ci    for (size_t i = 0; i < parameterNumber; i++) {
380ca0551cfSopenharmony_ci        mm->parameters_[i] = WriteMetaParameter(method->GetParameter(i));
381ca0551cfSopenharmony_ci    }
382ca0551cfSopenharmony_ci
383ca0551cfSopenharmony_ci    return mm;
384ca0551cfSopenharmony_ci}
385ca0551cfSopenharmony_ci
386ca0551cfSopenharmony_ciMetaParameter* MetadataBuilder::WriteMetaParameter(ASTParameter* parameter)
387ca0551cfSopenharmony_ci{
388ca0551cfSopenharmony_ci    // begin address
389ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_);
390ca0551cfSopenharmony_ci    MetaParameter* mp = reinterpret_cast<MetaParameter*>(baseAddr_);
391ca0551cfSopenharmony_ci    mp->name_ = WriteString(parameter->GetName());
392ca0551cfSopenharmony_ci    if (parameter->IsInParameter()) {
393ca0551cfSopenharmony_ci        mp->attributes_ |= ATTR_IN;
394ca0551cfSopenharmony_ci    }
395ca0551cfSopenharmony_ci    if (parameter->IsOutParameter()) {
396ca0551cfSopenharmony_ci        mp->attributes_ |= ATTR_OUT;
397ca0551cfSopenharmony_ci    }
398ca0551cfSopenharmony_ci    mp->typeIndex_ = module_->IndexOf(parameter->GetType());
399ca0551cfSopenharmony_ci    // end address
400ca0551cfSopenharmony_ci    baseAddr_ = baseAddr_ + sizeof(MetaParameter);
401ca0551cfSopenharmony_ci
402ca0551cfSopenharmony_ci    return mp;
403ca0551cfSopenharmony_ci}
404ca0551cfSopenharmony_ci
405ca0551cfSopenharmony_ciMetaType* MetadataBuilder::WriteMetaType(ASTType* type)
406ca0551cfSopenharmony_ci{
407ca0551cfSopenharmony_ci    // begin address
408ca0551cfSopenharmony_ci    baseAddr_ = ALIGN8(baseAddr_);
409ca0551cfSopenharmony_ci    MetaType* mt = reinterpret_cast<MetaType*>(baseAddr_);
410ca0551cfSopenharmony_ci    mt->kind_ = Type2Kind(type);
411ca0551cfSopenharmony_ci    if (type->IsSequenceableType()) {
412ca0551cfSopenharmony_ci        mt->index_ = module_->IndexOf(static_cast<ASTSequenceableType*>(type));
413ca0551cfSopenharmony_ci    } else if (type->IsInterfaceType()) {
414ca0551cfSopenharmony_ci        mt->index_ = module_->IndexOf(static_cast<ASTInterfaceType*>(type));
415ca0551cfSopenharmony_ci    } else {
416ca0551cfSopenharmony_ci        mt->index_ = module_->IndexOf(type);
417ca0551cfSopenharmony_ci    }
418ca0551cfSopenharmony_ci    baseAddr_ = baseAddr_ + sizeof(MetaType);
419ca0551cfSopenharmony_ci    if (type->IsListType()) {
420ca0551cfSopenharmony_ci        mt->nestedTypeNumber_ = 1;
421ca0551cfSopenharmony_ci        // nestedTypeIndexes_'s address
422ca0551cfSopenharmony_ci        baseAddr_ = ALIGN8(baseAddr_);
423ca0551cfSopenharmony_ci        mt->nestedTypeIndexes_ = reinterpret_cast<int*>(baseAddr_);
424ca0551cfSopenharmony_ci        AutoPtr<ASTType> elementType = (static_cast<ASTListType*>(type))->GetElementType();
425ca0551cfSopenharmony_ci        mt->nestedTypeIndexes_[0] = module_->IndexOf(elementType);
426ca0551cfSopenharmony_ci        // end address
427ca0551cfSopenharmony_ci        baseAddr_ = baseAddr_ + sizeof(int*);
428ca0551cfSopenharmony_ci    } else if (type->IsMapType()) {
429ca0551cfSopenharmony_ci        size_t typeNumber = 2;
430ca0551cfSopenharmony_ci        mt->nestedTypeNumber_ = static_cast<int>(typeNumber);
431ca0551cfSopenharmony_ci        // nestedTypeIndexes_'s address
432ca0551cfSopenharmony_ci        baseAddr_ = ALIGN8(baseAddr_);
433ca0551cfSopenharmony_ci        mt->nestedTypeIndexes_ = reinterpret_cast<int*>(baseAddr_);
434ca0551cfSopenharmony_ci        AutoPtr<ASTType> keyType = (static_cast<ASTMapType*>(type))->GetKeyType();
435ca0551cfSopenharmony_ci        AutoPtr<ASTType> valueType = (static_cast<ASTMapType*>(type))->GetValueType();
436ca0551cfSopenharmony_ci        mt->nestedTypeIndexes_[0] = module_->IndexOf(keyType);
437ca0551cfSopenharmony_ci        mt->nestedTypeIndexes_[1] = module_->IndexOf(valueType);
438ca0551cfSopenharmony_ci        // end address
439ca0551cfSopenharmony_ci        baseAddr_ = baseAddr_ + sizeof(int*) * typeNumber;
440ca0551cfSopenharmony_ci    } else if (type->IsArrayType()) {
441ca0551cfSopenharmony_ci        mt->nestedTypeNumber_ = 1;
442ca0551cfSopenharmony_ci        // nestedTypeIndexes_'s address
443ca0551cfSopenharmony_ci        baseAddr_ = ALIGN8(baseAddr_);
444ca0551cfSopenharmony_ci        mt->nestedTypeIndexes_ = reinterpret_cast<int*>(baseAddr_);
445ca0551cfSopenharmony_ci        AutoPtr<ASTType> elementType = (static_cast<ASTArrayType*>(type))->GetElementType();
446ca0551cfSopenharmony_ci        mt->nestedTypeIndexes_[0] = module_->IndexOf(elementType);
447ca0551cfSopenharmony_ci        // end address
448ca0551cfSopenharmony_ci        baseAddr_ = baseAddr_ + sizeof(int*);
449ca0551cfSopenharmony_ci    }
450ca0551cfSopenharmony_ci
451ca0551cfSopenharmony_ci    return mt;
452ca0551cfSopenharmony_ci}
453ca0551cfSopenharmony_ci
454ca0551cfSopenharmony_cichar* MetadataBuilder::WriteString(const String& string)
455ca0551cfSopenharmony_ci{
456ca0551cfSopenharmony_ci    return string.IsNull() ? nullptr : metaComponent_->stringPool_ + stringPool_.GetOffset(string);
457ca0551cfSopenharmony_ci}
458ca0551cfSopenharmony_ci
459ca0551cfSopenharmony_ciTypeKind MetadataBuilder::Type2Kind(ASTType* type)
460ca0551cfSopenharmony_ci{
461ca0551cfSopenharmony_ci    if (type->IsCharType()) {
462ca0551cfSopenharmony_ci        return TypeKind::Char;
463ca0551cfSopenharmony_ci    } else if (type->IsBooleanType()) {
464ca0551cfSopenharmony_ci        return TypeKind::Boolean;
465ca0551cfSopenharmony_ci    } else if (type->IsByteType()) {
466ca0551cfSopenharmony_ci        return TypeKind::Byte;
467ca0551cfSopenharmony_ci    } else if (type->IsShortType()) {
468ca0551cfSopenharmony_ci        return TypeKind::Short;
469ca0551cfSopenharmony_ci    } else if (type->IsIntegerType()) {
470ca0551cfSopenharmony_ci        return TypeKind::Integer;
471ca0551cfSopenharmony_ci    } else if (type->IsLongType()) {
472ca0551cfSopenharmony_ci        return TypeKind::Long;
473ca0551cfSopenharmony_ci    } else if (type->IsFloatType()) {
474ca0551cfSopenharmony_ci        return TypeKind::Float;
475ca0551cfSopenharmony_ci    } else if (type->IsDoubleType()) {
476ca0551cfSopenharmony_ci        return TypeKind::Double;
477ca0551cfSopenharmony_ci    } else if (type->IsStringType()) {
478ca0551cfSopenharmony_ci        return TypeKind::String;
479ca0551cfSopenharmony_ci    } else if (type->IsVoidType()) {
480ca0551cfSopenharmony_ci        return TypeKind::Void;
481ca0551cfSopenharmony_ci    } else if (type->IsSequenceableType()) {
482ca0551cfSopenharmony_ci        return TypeKind::Sequenceable;
483ca0551cfSopenharmony_ci    } else if (type->IsInterfaceType()) {
484ca0551cfSopenharmony_ci        return TypeKind::Interface;
485ca0551cfSopenharmony_ci    } else if (type->IsListType()) {
486ca0551cfSopenharmony_ci        return TypeKind::List;
487ca0551cfSopenharmony_ci    } else if (type->IsMapType()) {
488ca0551cfSopenharmony_ci        return TypeKind::Map;
489ca0551cfSopenharmony_ci    } else if (type->IsArrayType()) {
490ca0551cfSopenharmony_ci        return TypeKind::Array;
491ca0551cfSopenharmony_ci    }
492ca0551cfSopenharmony_ci    return TypeKind::Unknown;
493ca0551cfSopenharmony_ci}
494ca0551cfSopenharmony_ci} // namespace Idl
495ca0551cfSopenharmony_ci} // namespace OHOS
496