1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16
17 #define JSON_IMPL
18 #include "json_output.h"
19
20 #include <base/containers/vector.h>
21 #include <base/util/uid_util.h>
22 #include <core/json/json.h>
23
24 #include <meta/base/namespace.h>
25 #include <meta/base/plugin.h>
26 #include <meta/base/ref_uri.h>
27 #include <meta/ext/minimal_object.h>
28
29 META_BEGIN_NAMESPACE()
30
31 namespace Serialization {
32
33
34 META_REGISTER_CLASS(Visitor, "2838202a-b362-4715-96ed-59f19334b3ac", ObjectCategoryBits::NO_CATEGORY)
35
36 struct Visitor : IntroduceInterfaces<MinimalObject, ISerNodeVisitor> {
META_IMPLEMENT_OBJECT_TYPE_INTERFACESerialization::Visitor37 META_IMPLEMENT_OBJECT_TYPE_INTERFACE(ClassId::Visitor)
38
39 json_value GetValue()
40 {
41 return BASE_NS::move(node_);
42 }
43
44 private:
VisitSerialization::Visitor45 void Visit(const IRootNode&) override
46 {
47 CORE_LOG_E("Second root node, ignoring...");
48 }
VisitSerialization::Visitor49 void Visit(const INilNode&) override
50 {
51 node_ = json_value::null {};
52 }
VisitSerialization::Visitor53 void Visit(const IObjectNode& n) override
54 {
55 json_value::object object;
56 if (n.GetObjectId().IsValid() && n.GetMembers()) {
57 Visitor v;
58 n.GetMembers()->Apply(v);
59 auto value = v.GetValue();
60 if (value.is_object()) {
61 object.emplace_back("$classId", json_value::string(n.GetObjectId().ToString()));
62 if (!n.GetObjectClassName().empty()) {
63 object.emplace_back("$className", json_value::string(n.GetObjectClassName()));
64 }
65 if (!n.GetObjectName().empty() && n.GetObjectName() != n.GetInstanceId().ToString()) {
66 object.emplace_back("$name", json_value::string(n.GetObjectName()));
67 }
68 if (n.GetInstanceId().IsValid()) {
69 object.emplace_back("$instanceId", json_value::string(n.GetInstanceId().ToString()));
70 }
71 json_value::object obj = value.object_;
72 object.insert(object.end(), obj.begin(), obj.end());
73 }
74 }
75 node_ = BASE_NS::move(object);
76 }
VisitSerialization::Visitor77 void Visit(const IArrayNode& n) override
78 {
79 auto members = n.GetMembers();
80 json_value::array array;
81 array.reserve(members.size());
82 for (auto&& m : members) {
83 Visitor v;
84 m->Apply(v);
85 array.emplace_back(v.GetValue());
86 }
87 node_ = BASE_NS::move(array);
88 }
VisitSerialization::Visitor89 void Visit(const IMapNode& n) override
90 {
91 auto members = n.GetMembers();
92 json_value::object object;
93 for (auto&& m : members) {
94 Visitor v;
95 m.node->Apply(v);
96 object.emplace_back(BASE_NS::move(m.name), v.GetValue());
97 }
98 node_ = BASE_NS::move(object);
99 }
VisitSerialization::Visitor100 void Visit(const IBuiltinValueNode<bool>& n) override
101 {
102 node_ = json_value { n.GetValue() };
103 }
VisitSerialization::Visitor104 void Visit(const IBuiltinValueNode<double>& n) override
105 {
106 node_ = json_value { n.GetValue() };
107 }
VisitSerialization::Visitor108 void Visit(const IBuiltinValueNode<int64_t>& n) override
109 {
110 node_ = json_value { n.GetValue() };
111 }
VisitSerialization::Visitor112 void Visit(const IBuiltinValueNode<uint64_t>& n) override
113 {
114 node_ = json_value { n.GetValue() };
115 }
VisitSerialization::Visitor116 void Visit(const IBuiltinValueNode<BASE_NS::string>& n) override
117 {
118 node_ = json_value { n.GetValue() };
119 }
VisitSerialization::Visitor120 void Visit(const IBuiltinValueNode<RefUri>& n) override
121 {
122 json_value::object object;
123 object.emplace_back("$ref", n.GetValue().ToString());
124 node_ = BASE_NS::move(object);
125 }
VisitSerialization::Visitor126 void Visit(const ISerNode&) override
127 {
128 CORE_LOG_E("Unknown node type");
129 }
130
131 private:
132 json_value node_;
133 };
134
MetadataObject(const IRootNode & root)135 json_value MetadataObject(const IRootNode& root)
136 {
137 json_value::object object;
138 object.emplace_back("meta-version", json_value::string(META_VERSION.ToString()));
139 object.emplace_back("version", json_value::string(root.GetVersion().ToString()));
140 object.emplace_back("exporter-version", json_value::string(root.GetSerializerVersion().ToString()));
141 return object;
142 }
143
Process(const ISerNode::Ptr & tree)144 BASE_NS::string JsonOutput::Process(const ISerNode::Ptr& tree)
145 {
146 CORE_NS::json::standalone_value res;
147
148 if (auto root = interface_cast<IRootNode>(tree)) {
149 if (root->GetObject()) {
150 json_value::object object;
151 object.emplace_back("$meta", MetadataObject(*root));
152
153 Visitor v;
154 root->GetObject()->Apply(v);
155 auto node = v.GetValue();
156 if (node.is_object()) {
157 object.emplace_back("$root", BASE_NS::move(node));
158 res = BASE_NS::move(object);
159 } else {
160 CORE_LOG_E("failed to output root node object");
161 }
162 } else {
163 CORE_LOG_E("root node did not contain object");
164 }
165 }
166 return CORE_NS::json::to_string(res);
167 }
168
169 } // namespace Serialization
170
171 META_END_NAMESPACE()
172