blob: b289076f5010e217d1663443a82c074154393ac6 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/shell/common/result.h"
#include <lib/syslog/cpp/macros.h>
#include <ostream>
#include "fidl/fuchsia.shell/cpp/wire.h"
namespace shell::common {
std::unique_ptr<ResultNode> DeserializeResult::Deserialize(
const fidl::VectorView<fuchsia_shell::wire::Node>& nodes) {
FX_DCHECK(!nodes.empty());
return DeserializeNode(nodes, nodes.count());
}
std::unique_ptr<ResultNode> DeserializeResult::DeserializeNode(
const fidl::VectorView<fuchsia_shell::wire::Node>& nodes, uint64_t node_id) {
FX_DCHECK(node_id <= nodes.count());
const fuchsia_shell::wire::Node& node = nodes[node_id - 1];
if (node.is_integer_literal()) {
return std::make_unique<ResultNodeIntegerLiteral>(node.integer_literal().absolute_value,
node.integer_literal().negative);
}
if (node.is_string_literal()) {
return std::make_unique<ResultNodeStringLiteral>(node.string_literal());
}
if (node.is_object()) {
auto schema = DeserializeSchema(nodes, node.object().object_schema.node_id);
if (schema != nullptr) {
auto result = std::make_unique<ResultNodeObject>(schema);
for (const auto& field_id : node.object().fields) {
FX_DCHECK(field_id.file_id == 1U);
FX_DCHECK(field_id.node_id <= nodes.count());
const fuchsia_shell::wire::Node& field_node = nodes[field_id.node_id - 1];
FX_DCHECK(field_node.is_object_field());
FX_DCHECK(field_node.object_field().object_field_schema.file_id == 1U);
auto field_schema =
schema->SearchField(field_node.object_field().object_field_schema.node_id);
FX_DCHECK(field_schema != nullptr);
auto field_value = DeserializeNode(nodes, field_node.object_field().value.node_id);
if (field_value != nullptr) {
result->AddField(field_schema, std::move(field_value));
}
}
return result;
}
}
return nullptr;
}
std::shared_ptr<ResultSchema> DeserializeResult::DeserializeSchema(
const fidl::VectorView<fuchsia_shell::wire::Node>& nodes, uint64_t node_id) {
if (node_id == 0) {
return nullptr;
}
auto schema = schemas_.find(node_id);
if (schema != schemas_.end()) {
return schema->second;
}
FX_DCHECK(node_id <= nodes.count());
const fuchsia_shell::wire::Node& schema_node = nodes[node_id - 1];
if (!schema_node.is_object_schema()) {
return nullptr;
}
auto result = std::make_shared<ResultSchema>();
schemas_.emplace(std::pair(node_id, result));
for (const auto& field : schema_node.object_schema().fields) {
FX_DCHECK(field.file_id == 1U);
uint64_t field_id = field.node_id;
FX_DCHECK(field_id <= nodes.count());
const fuchsia_shell::wire::Node& schema_field_node = nodes[field_id - 1];
if (schema_field_node.is_field_schema()) {
result->AddField(field_id, schema_field_node.field_schema().name,
DeserializeType(nodes, schema_field_node.field_schema().type));
}
}
return result;
}
std::unique_ptr<ResultType> DeserializeResult::DeserializeType(
const fidl::VectorView<fuchsia_shell::wire::Node>& nodes,
const fuchsia_shell::wire::ShellType& shell_type) {
if (shell_type.is_builtin_type()) {
switch (shell_type.builtin_type()) {
case fuchsia_shell::wire::BuiltinType::kUint64:
return std::make_unique<ResultTypeUint64>();
case fuchsia_shell::wire::BuiltinType::kString:
return std::make_unique<ResultTypeString>();
default:
return nullptr;
}
}
return nullptr;
}
} // namespace shell::common