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 #define JSON_IMPL
16 #include "json_output.h"
17
18 #include <base/containers/vector.h>
19 #include <base/util/uid_util.h>
20 #include <core/json/json.h>
21
22 #include <meta/base/namespace.h>
23 #include <meta/base/plugin.h>
24 #include <meta/base/ref_uri.h>
25 #include <meta/ext/minimal_object.h>
26
27 META_BEGIN_NAMESPACE()
28
29 namespace Serialization {
30
31 constexpr Version CURRENT_JSON_VERSION(2, 0);
32
33 META_REGISTER_CLASS(Visitor, "2838202a-b362-4715-96ed-59f19334b3ac", ObjectCategoryBits::NO_CATEGORY)
34
35 struct Visitor : MinimalObject<ClassId::Visitor, ISerNodeVisitor> {
GetValueSerialization::Visitor36 json_value GetValue()
37 {
38 return BASE_NS::move(node_);
39 }
40
41 private:
VisitSerialization::Visitor42 void Visit(const IRootNode&) override
43 {
44 CORE_LOG_E("Second root node, ignoring...");
45 }
VisitSerialization::Visitor46 void Visit(const INilNode&) override
47 {
48 node_ = json_value::null {};
49 }
VisitSerialization::Visitor50 void Visit(const IObjectNode& n) override
51 {
52 json_value::object object;
53 if (n.GetObjectId().IsValid() && n.GetMembers()) {
54 Visitor v;
55 n.GetMembers()->Apply(v);
56 auto value = v.GetValue();
57 if (value.is_object()) {
58 object.emplace_back("$classId", json_value::string(n.GetObjectId().ToString()));
59 if (!n.GetObjectClassName().empty()) {
60 object.emplace_back("$className", json_value::string(n.GetObjectClassName()));
61 }
62 if (!n.GetObjectName().empty() && n.GetObjectName() != n.GetInstanceId().ToString()) {
63 object.emplace_back("$name", json_value::string(n.GetObjectName()));
64 }
65 if (n.GetInstanceId().IsValid()) {
66 object.emplace_back("$instanceId", json_value::string(n.GetInstanceId().ToString()));
67 }
68 json_value::object obj = value.object_;
69 object.insert(object.end(), obj.begin(), obj.end());
70 }
71 }
72 node_ = BASE_NS::move(object);
73 }
VisitSerialization::Visitor74 void Visit(const IArrayNode& n) override
75 {
76 auto members = n.GetMembers();
77 json_value::array array;
78 array.reserve(members.size());
79 for (auto&& m : members) {
80 Visitor v;
81 m->Apply(v);
82 array.emplace_back(v.GetValue());
83 }
84 node_ = BASE_NS::move(array);
85 }
VisitSerialization::Visitor86 void Visit(const IMapNode& n) override
87 {
88 auto members = n.GetMembers();
89 json_value::object object;
90 for (auto&& m : members) {
91 Visitor v;
92 m.node->Apply(v);
93 object.emplace_back(BASE_NS::move(m.name), v.GetValue());
94 }
95 node_ = BASE_NS::move(object);
96 }
VisitSerialization::Visitor97 void Visit(const IBuiltinValueNode<bool>& n) override
98 {
99 node_ = json_value { n.GetValue() };
100 }
VisitSerialization::Visitor101 void Visit(const IBuiltinValueNode<double>& n) override
102 {
103 node_ = json_value { n.GetValue() };
104 }
VisitSerialization::Visitor105 void Visit(const IBuiltinValueNode<int64_t>& n) override
106 {
107 node_ = json_value { n.GetValue() };
108 }
VisitSerialization::Visitor109 void Visit(const IBuiltinValueNode<uint64_t>& n) override
110 {
111 node_ = json_value { n.GetValue() };
112 }
VisitSerialization::Visitor113 void Visit(const IBuiltinValueNode<BASE_NS::string>& n) override
114 {
115 node_ = json_value { n.GetValue() };
116 }
VisitSerialization::Visitor117 void Visit(const IBuiltinValueNode<RefUri>& n) override
118 {
119 json_value::object object;
120 object.emplace_back("$ref", n.GetValue().ToString());
121 node_ = BASE_NS::move(object);
122 }
VisitSerialization::Visitor123 void Visit(const ISerNode&) override
124 {
125 CORE_LOG_E("Unknown node type");
126 }
127
128 private:
129 json_value node_;
130 };
131
MetadataObject(const IRootNode & root)132 json_value MetadataObject(const IRootNode& root)
133 {
134 json_value::object object;
135 object.emplace_back("meta-version", json_value::string(META_VERSION.ToString()));
136 object.emplace_back("version", json_value::string(CURRENT_JSON_VERSION.ToString()));
137 object.emplace_back("exporter-version", json_value::string(root.GetSerializerVersion().ToString()));
138 return object;
139 }
140
Process(const ISerNode::Ptr & tree)141 BASE_NS::string JsonOutput::Process(const ISerNode::Ptr& tree)
142 {
143 CORE_NS::json::standalone_value res;
144
145 if (auto root = interface_cast<IRootNode>(tree)) {
146 if (root->GetObject()) {
147 json_value::object object;
148 object.emplace_back("$meta", MetadataObject(*root));
149
150 Visitor v;
151 root->GetObject()->Apply(v);
152 auto node = v.GetValue();
153 if (node.is_object()) {
154 object.emplace_back("$root", BASE_NS::move(node));
155 res = BASE_NS::move(object);
156 } else {
157 CORE_LOG_E("failed to output root node object");
158 }
159 } else {
160 CORE_LOG_E("root node did not contain object");
161 }
162 }
163 return CORE_NS::json::to_string(res);
164 }
165
166 } // namespace Serialization
167
168 META_END_NAMESPACE()
169