| // Copyright 2017 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 "peridot/bin/module_resolver/type_inference.h" |
| |
| #include <string> |
| #include <vector> |
| |
| #include <lib/async/cpp/operation.h> |
| #include <lib/entity/cpp/json.h> |
| #include <lib/fsl/types/type_converters.h> |
| #include <src/lib/fxl/macros.h> |
| |
| namespace modular { |
| |
| ParameterTypeInferenceHelper::ParameterTypeInferenceHelper( |
| fuchsia::modular::EntityResolverPtr entity_resolver) |
| : entity_resolver_(std::move(entity_resolver)) {} |
| |
| ParameterTypeInferenceHelper::~ParameterTypeInferenceHelper() = default; |
| |
| class ParameterTypeInferenceHelper::GetParameterTypesCall |
| : public Operation<std::vector<std::string>> { |
| public: |
| GetParameterTypesCall(fuchsia::modular::EntityResolver* entity_resolver, |
| const fidl::StringPtr& entity_reference, |
| ResultCall result) |
| : Operation("ParameterTypeInferenceHelper::GetParameterTypesCall", |
| std::move(result)), |
| entity_resolver_(entity_resolver), |
| entity_reference_(entity_reference) {} |
| |
| void Run() { |
| entity_resolver_->ResolveEntity(entity_reference_, entity_.NewRequest()); |
| entity_->GetTypes([this](const fidl::VectorPtr<fidl::StringPtr>& types) { |
| Done(fidl::To<std::vector<std::string>>(types)); |
| }); |
| } |
| |
| private: |
| fuchsia::modular::EntityResolver* const entity_resolver_; |
| fidl::StringPtr const entity_reference_; |
| fuchsia::modular::EntityPtr entity_; |
| }; |
| |
| void ParameterTypeInferenceHelper::GetParameterTypes( |
| const fuchsia::modular::ResolverParameterConstraint& parameter_constraint, |
| fit::function<void(std::vector<std::string>)> result_callback) { |
| if (parameter_constraint.is_entity_type()) { |
| result_callback( |
| std::vector<std::string>(parameter_constraint.entity_type()->begin(), |
| parameter_constraint.entity_type()->end())); |
| } else if (parameter_constraint.is_json()) { |
| std::vector<std::string> types; |
| if (!ExtractEntityTypesFromJson(parameter_constraint.json(), &types)) { |
| FXL_LOG(WARNING) << "Mal-formed JSON in parameter: " |
| << parameter_constraint.json(); |
| result_callback({}); |
| } else { |
| result_callback(types); |
| } |
| } else if (parameter_constraint.is_entity_reference()) { |
| operation_collection_.Add(std::make_unique<GetParameterTypesCall>( |
| entity_resolver_.get(), parameter_constraint.entity_reference(), |
| result_callback)); |
| } else if (parameter_constraint.is_link_info()) { |
| if (parameter_constraint.link_info().allowed_types) { |
| std::vector<std::string> types( |
| parameter_constraint.link_info() |
| .allowed_types->allowed_entity_types->begin(), |
| parameter_constraint.link_info() |
| .allowed_types->allowed_entity_types->end()); |
| result_callback(std::move(types)); |
| } else if (parameter_constraint.link_info().content_snapshot) { |
| // TODO(thatguy): See if there's an fuchsia::modular::Entity reference on |
| // the fuchsia::modular::Link. If so, get the types from that. If |
| // resolution results in a Module being started, this |
| // fuchsia::modular::Link should have its allowed types constrained, since |
| // *another* Module is now relying on a small set of types being set. |
| // Consider doing this when we move type extraction to the Framework and |
| // simplify the Resolver. |
| std::string entity_reference; |
| if (EntityReferenceFromJson( |
| parameter_constraint.link_info().content_snapshot, |
| &entity_reference)) { |
| operation_collection_.Add(std::make_unique<GetParameterTypesCall>( |
| entity_resolver_.get(), entity_reference, result_callback)); |
| } |
| } |
| } else { |
| FXL_NOTREACHED(); |
| } |
| } |
| |
| } // namespace modular |