source/model-generator/ModelTemplates.h (302 lines of code) (raw):
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <mariana-trench/Access.h>
#include <mariana-trench/Context.h>
#include <mariana-trench/Frame.h>
#include <mariana-trench/Model.h>
#include <mariana-trench/model-generator/ModelGenerator.h>
namespace marianatrench {
class TemplateVariableMapping final {
public:
TemplateVariableMapping();
TemplateVariableMapping(const TemplateVariableMapping&) = default;
TemplateVariableMapping(TemplateVariableMapping&&) = default;
TemplateVariableMapping& operator=(const TemplateVariableMapping&) = default;
TemplateVariableMapping& operator=(TemplateVariableMapping&&) = default;
~TemplateVariableMapping() = default;
void insert(const std::string& name, ParameterPosition index);
std::optional<ParameterPosition> at(const std::string& name) const;
private:
std::unordered_map<std::string, ParameterPosition> map_;
};
/* Store either an integer typed parameter position, or a string typed parameter
* position (which is its name and can be instantiated when given a mapping from
* variable names to variable indices) */
class ParameterPositionTemplate final {
public:
explicit ParameterPositionTemplate(ParameterPosition parameter_position);
explicit ParameterPositionTemplate(std::string parameter_position);
ParameterPositionTemplate(const ParameterPositionTemplate&) = default;
ParameterPositionTemplate(ParameterPositionTemplate&&) = default;
ParameterPositionTemplate& operator=(const ParameterPositionTemplate&) =
default;
ParameterPositionTemplate& operator=(ParameterPositionTemplate&&) = default;
~ParameterPositionTemplate() = default;
ParameterPosition instantiate(
const TemplateVariableMapping& parameter_positions) const;
std::string to_string() const;
private:
std::variant<ParameterPosition, std::string> parameter_position_;
};
class RootTemplate final {
public:
explicit RootTemplate(
Root::Kind kind,
std::optional<ParameterPositionTemplate> parameter_position =
std::nullopt);
RootTemplate(const RootTemplate&) = default;
RootTemplate(RootTemplate&&) = default;
RootTemplate& operator=(const RootTemplate&) = default;
RootTemplate& operator=(RootTemplate&&) = default;
~RootTemplate() = default;
bool is_argument() const;
Root instantiate(const TemplateVariableMapping& parameter_positions) const;
std::string to_string() const;
private:
Root::Kind kind_;
std::optional<ParameterPositionTemplate> parameter_position_;
};
class AccessPathTemplate final {
public:
explicit AccessPathTemplate(RootTemplate root, Path path = {});
AccessPathTemplate(const AccessPathTemplate&) = default;
AccessPathTemplate(AccessPathTemplate&&) = default;
AccessPathTemplate& operator=(const AccessPathTemplate&) = delete;
AccessPathTemplate& operator=(AccessPathTemplate&&) = delete;
~AccessPathTemplate() = default;
const RootTemplate& root() const {
return root_;
}
const Path& path() const {
return path_;
}
static AccessPathTemplate from_json(const Json::Value& value);
Json::Value to_json() const;
AccessPath instantiate(
const TemplateVariableMapping& parameter_positions) const;
private:
RootTemplate root_;
Path path_;
};
class PropagationTemplate final {
public:
explicit PropagationTemplate(
AccessPathTemplate input,
AccessPathTemplate output,
FeatureMayAlwaysSet inferred_features,
FeatureSet user_features);
PropagationTemplate(const PropagationTemplate&) = default;
PropagationTemplate(PropagationTemplate&&) = default;
PropagationTemplate& operator=(const PropagationTemplate&) = delete;
PropagationTemplate& operator=(PropagationTemplate&&) = delete;
~PropagationTemplate() = default;
static PropagationTemplate from_json(
const Json::Value& value,
Context& context);
void instantiate(
const TemplateVariableMapping& parameter_positions,
Model& model) const;
private:
AccessPathTemplate input_;
AccessPathTemplate output_;
FeatureMayAlwaysSet inferred_features_;
FeatureSet user_features_;
};
class SinkTemplate final {
public:
explicit SinkTemplate(Frame sink, AccessPathTemplate port);
SinkTemplate(const SinkTemplate&) = default;
SinkTemplate(SinkTemplate&&) = default;
SinkTemplate& operator=(const SinkTemplate&) = delete;
SinkTemplate& operator=(SinkTemplate&&) = delete;
~SinkTemplate() = default;
static SinkTemplate from_json(const Json::Value& value, Context& context);
void instantiate(
const TemplateVariableMapping& parameter_positions,
Model& model) const;
private:
Frame sink_;
AccessPathTemplate port_;
};
class ParameterSourceTemplate final {
public:
explicit ParameterSourceTemplate(Frame source, AccessPathTemplate port);
ParameterSourceTemplate(const ParameterSourceTemplate&) = default;
ParameterSourceTemplate(ParameterSourceTemplate&&) = default;
ParameterSourceTemplate& operator=(const ParameterSourceTemplate&) = delete;
ParameterSourceTemplate& operator=(ParameterSourceTemplate&&) = delete;
~ParameterSourceTemplate() = default;
static ParameterSourceTemplate from_json(
const Json::Value& value,
Context& context);
void instantiate(
const TemplateVariableMapping& parameter_positions,
Model& model) const;
private:
Frame source_;
AccessPathTemplate port_;
};
class GenerationTemplate final {
public:
explicit GenerationTemplate(Frame source, AccessPathTemplate port);
GenerationTemplate(const GenerationTemplate&) = default;
GenerationTemplate(GenerationTemplate&&) = default;
GenerationTemplate& operator=(const GenerationTemplate&) = delete;
GenerationTemplate& operator=(GenerationTemplate&&) = delete;
~GenerationTemplate() = default;
static GenerationTemplate from_json(
const Json::Value& value,
Context& context);
void instantiate(
const TemplateVariableMapping& parameter_positions,
Model& model) const;
private:
Frame source_;
AccessPathTemplate port_;
};
class SourceTemplate final {
public:
explicit SourceTemplate(Frame source, AccessPathTemplate port);
SourceTemplate(const SourceTemplate&) = default;
SourceTemplate(SourceTemplate&&) = default;
SourceTemplate& operator=(const SourceTemplate&) = delete;
SourceTemplate& operator=(SourceTemplate&&) = delete;
~SourceTemplate() = default;
static SourceTemplate from_json(const Json::Value& value, Context& context);
void instantiate(
const TemplateVariableMapping& parameter_positions,
Model& model) const;
private:
Frame source_;
AccessPathTemplate port_;
};
class AttachToSourcesTemplate final {
public:
explicit AttachToSourcesTemplate(FeatureSet features, RootTemplate port);
AttachToSourcesTemplate(const AttachToSourcesTemplate&) = default;
AttachToSourcesTemplate(AttachToSourcesTemplate&&) = default;
AttachToSourcesTemplate& operator=(const AttachToSourcesTemplate&) = delete;
AttachToSourcesTemplate& operator=(AttachToSourcesTemplate&&) = delete;
~AttachToSourcesTemplate() = default;
static AttachToSourcesTemplate from_json(
const Json::Value& value,
Context& context);
void instantiate(
const TemplateVariableMapping& parameter_positions,
Model& model) const;
private:
FeatureSet features_;
RootTemplate port_;
};
class AttachToSinksTemplate final {
public:
explicit AttachToSinksTemplate(FeatureSet features, RootTemplate port);
AttachToSinksTemplate(const AttachToSinksTemplate&) = default;
AttachToSinksTemplate(AttachToSinksTemplate&&) = default;
AttachToSinksTemplate& operator=(const AttachToSinksTemplate&) = delete;
AttachToSinksTemplate& operator=(AttachToSinksTemplate&&) = delete;
~AttachToSinksTemplate() = default;
static AttachToSinksTemplate from_json(
const Json::Value& value,
Context& context);
void instantiate(
const TemplateVariableMapping& parameter_positions,
Model& model) const;
private:
FeatureSet features_;
RootTemplate port_;
};
class AttachToPropagationsTemplate final {
public:
explicit AttachToPropagationsTemplate(FeatureSet features, RootTemplate port);
AttachToPropagationsTemplate(const AttachToPropagationsTemplate&) = default;
AttachToPropagationsTemplate(AttachToPropagationsTemplate&&) = default;
AttachToPropagationsTemplate& operator=(const AttachToPropagationsTemplate&) =
delete;
AttachToPropagationsTemplate& operator=(AttachToPropagationsTemplate&&) =
delete;
~AttachToPropagationsTemplate() = default;
static AttachToPropagationsTemplate from_json(
const Json::Value& value,
Context& context);
void instantiate(
const TemplateVariableMapping& parameter_positions,
Model& model) const;
private:
FeatureSet features_;
RootTemplate port_;
};
class AddFeaturesToArgumentsTemplate final {
public:
explicit AddFeaturesToArgumentsTemplate(
FeatureSet features,
RootTemplate port);
AddFeaturesToArgumentsTemplate(const AddFeaturesToArgumentsTemplate&) =
default;
AddFeaturesToArgumentsTemplate(AddFeaturesToArgumentsTemplate&&) = default;
AddFeaturesToArgumentsTemplate& operator=(
const AddFeaturesToArgumentsTemplate&) = delete;
AddFeaturesToArgumentsTemplate& operator=(AddFeaturesToArgumentsTemplate&&) =
delete;
~AddFeaturesToArgumentsTemplate() = default;
static AddFeaturesToArgumentsTemplate from_json(
const Json::Value& value,
Context& context);
void instantiate(
const TemplateVariableMapping& parameter_positions,
Model& model) const;
private:
FeatureSet features_;
RootTemplate port_;
};
class ForAllParameters final {
public:
explicit ForAllParameters(
std::unique_ptr<AllOfTypeConstraint> constraints,
std::string variable,
std::vector<SinkTemplate> sink_templates = {},
std::vector<ParameterSourceTemplate> parameter_source_templates = {},
std::vector<GenerationTemplate> generation_templates = {},
std::vector<SourceTemplate> source_templates = {},
std::vector<PropagationTemplate> propagation_templates = {},
std::vector<AttachToSourcesTemplate> attach_to_sources_templates = {},
std::vector<AttachToSinksTemplate> attach_to_sinks_templates = {},
std::vector<AttachToPropagationsTemplate>
attach_to_propagations_templates = {},
std::vector<AddFeaturesToArgumentsTemplate>
add_features_to_arguments_templates = {});
ForAllParameters(const ForAllParameters& other) = delete;
ForAllParameters(ForAllParameters&& other) = default;
ForAllParameters& operator=(const ForAllParameters& other) = delete;
ForAllParameters& operator=(ForAllParameters&& other) = delete;
static ForAllParameters from_json(const Json::Value&, Context& context);
/* Update a model with new sinks/generations/... when the model is/will be
* instantiated with the method. Return true if the model was updated. */
bool instantiate(Model& model, const Method* method) const;
private:
std::unique_ptr<AllOfTypeConstraint> constraints_;
std::string variable_;
std::vector<SinkTemplate> sink_templates_;
std::vector<ParameterSourceTemplate> parameter_source_templates_;
std::vector<GenerationTemplate> generation_templates_;
std::vector<SourceTemplate> source_templates_;
std::vector<PropagationTemplate> propagation_templates_;
std::vector<AttachToSourcesTemplate> attach_to_sources_templates_;
std::vector<AttachToSinksTemplate> attach_to_sinks_templates_;
std::vector<AttachToPropagationsTemplate> attach_to_propagations_templates_;
std::vector<AddFeaturesToArgumentsTemplate>
add_features_to_arguments_templates_;
};
class ModelTemplate final {
public:
/* The given `model` must not be associated with a method. */
ModelTemplate(
const Model& model,
std::vector<ForAllParameters> for_all_parameters);
ModelTemplate(const ModelTemplate& other) = delete;
ModelTemplate(ModelTemplate&& other) = default;
ModelTemplate& operator=(const ModelTemplate& other) = delete;
ModelTemplate& operator=(ModelTemplate&& other) = delete;
/* Create a model with information that is associated with a method (e.g. new
* sinks/generations/...). */
std::optional<Model> instantiate(Context& context, const Method* method)
const;
static ModelTemplate from_json(
const Json::Value& model_generator,
Context& context);
private:
Model model_;
std::vector<ForAllParameters> for_all_parameters_;
};
} // namespace marianatrench