{% import "mojolpm_macros.tmpl" as util %}
{%- macro declare_array(type, kind) %}
{%- set mojom_type = kind.kind|cpp_wrapper_type(add_same_module_namespaces=true) %}
{%- if kind.kind|is_nullable_kind %}
{%- set mojom_maybe_type = kind.kind|to_unnullable_kind|cpp_wrapper_type(add_same_module_namespaces=true) %}
{%- else %}
{%- set mojom_maybe_type = mojom_type %}
{%- endif %}
bool FromProto(
const {{type}}& input,
std::vector<{{mojom_type}}>& output);{{"\n"-}}
{%- if kind.kind|is_array_kind %}
{{declare_array(type ~ "Entry", kind.kind)}}
{%- elif kind.kind|is_map_kind %}
{{declare_map(type ~ "Entry", kind.kind)}}
{%- elif kind.kind|is_nullable_kind %}
bool FromProto(
const {{type}}Entry& input,
{{mojom_maybe_type}}& output);{{"\n"-}}
{%- else %}
bool FromProto(
const {{type}}Entry& input,
{{mojom_type}}& output);{{"\n"-}}
{%- endif %}
{%- endmacro %}
{%- macro declare_map(type, kind) %}
{%- set mojom_key_type = kind.key_kind|cpp_wrapper_type(add_same_module_namespaces=true) %}
{%- set mojom_value_type = kind.value_kind|cpp_wrapper_type(add_same_module_namespaces=true) %}
{%- if kind.value_kind|is_nullable_kind %}
{%- set mojom_maybe_value_type = kind.value_kind|to_unnullable_kind|cpp_wrapper_type(add_same_module_namespaces=true) %}
{%- else %}
{%- set mojom_maybe_value_type = mojom_value_type %}
{%- endif %}
bool FromProto(
const {{type}}& input,
base::flat_map<{{mojom_key_type}},
{{mojom_value_type}}>& output);{{"\n"-}}
{%- if kind.key_kind|is_array_kind %}
{{- declare_array(type ~ "Key", kind.key_kind)}}
{%- elif kind.key_kind|is_map_kind %}
{{- declare_map(type ~ "Key", kind.key_kind)}}
{%- else %}
bool FromProto(
const {{type}}Key& input,
{{mojom_key_type}}& output);{{"\n"-}}
{%- endif %}
{%- if kind.value_kind|is_array_kind %}
{{- declare_array(type ~ "Value", kind.value_kind)}}
{%- elif kind.value_kind|is_map_kind %}
{{- declare_map(type ~ "Value", kind.value_kind)}}
{%- elif kind.value_kind|is_nullable_kind %}
bool FromProto(
const {{type}}Value& input,
{{mojom_maybe_value_type}}& output);{{"\n"-}}
{%- else %}
bool FromProto(
const {{type}}Value& input,
{{mojom_value_type}}& output);{{"\n"-}}
{%- endif %}
{%- endmacro %}
{%- macro declare(parent_name, kind, name) %}
{%- if kind|is_array_kind %}
{%- set array_type = parent_name ~ "::" ~ name|under_to_camel ~ "_Array" %}
{{- declare_array(array_type, kind)}}
{%- elif kind|is_map_kind %}
{%- set map_type = parent_name ~ "::" ~ name|under_to_camel ~ "_Map" %}
{{- declare_map(map_type, kind)}}
{%- endif %}
{%- endmacro %}
{%- macro define_array(type, kind) %}
{%- set mojom_type = kind.kind|cpp_wrapper_type(add_same_module_namespaces=true) %}
bool FromProto(
const {{type}}& input,
std::vector<{{mojom_type}}>& output) {
bool result = true;
output.reserve(input.values_size());
for (const auto& entry : input.values()) {
{{mojom_type}} value{ {{- kind.kind|default_constructor_args -}} };
{%- if kind.kind|is_nullable_kind %}
{%- set unnullable_kind = kind.kind|to_unnullable_kind %}
{%- set mojom_maybe_type = unnullable_kind|cpp_wrapper_type(add_same_module_namespaces=true) %}
{{mojom_maybe_type}} maybe_value{ {{- unnullable_kind|default_constructor_args -}} };
if (entry.has_value() && FromProto(entry.value(), maybe_value)) {
value = std::move(maybe_value);
}
{%- elif kind.kind|is_map_kind or kind.kind|is_array_kind %}
result = FromProto(entry, value);
if (!result) {
break;
}
{%- else %}
result = FromProto(entry.value(), value);
if (!result) {
break;
}
{%- endif %}
output.emplace_back(std::move(value));
}
return result;
}{{"\n"-}}
{%- if kind.kind|is_array_kind %}
{{- define_array(type ~ "Entry", kind.kind)}}
{%- elif kind.kind|is_map_kind %}
{{- define_map(type ~ "Entry", kind.kind)}}
{%- elif kind.kind|is_nullable_kind %}
bool FromProto(
const {{type}}Entry& input,
{{mojom_maybe_type}}& output) {
return FromProto(input.value(), output);
}{{"\n"-}}
{%- else %}
bool FromProto(
const {{type}}Entry& input,
{{mojom_type}}& output) {
return FromProto(input.value(), output);
}{{"\n"-}}
{%- endif %}
{%- endmacro %}
{%- macro define_map(type, kind) %}
{%- set mojom_key_type = kind.key_kind|cpp_wrapper_type(add_same_module_namespaces=true) %}
{%- set mojom_value_type = kind.value_kind|cpp_wrapper_type(add_same_module_namespaces=true) %}
bool FromProto(
const {{type}}& input,
base::flat_map<{{mojom_key_type}},
{{mojom_value_type}}>& output) {
bool result = true;
for (const auto& entry : input.values()) {
{%- if kind.value_kind|is_nullable_kind %}
{%- set unnullable_value_kind = kind.value_kind|to_unnullable_kind %}
{%- set mojom_maybe_value_type = unnullable_value_kind|cpp_wrapper_type(add_same_module_namespaces=true) %}
{{mojom_key_type}} key{ {{- kind.key_kind|default_constructor_args -}} };
{{mojom_value_type}} value{ {{- kind.value_kind|default_constructor_args -}} };
{{mojom_maybe_value_type}} maybe_value{ {{- unnullable_value_kind|default_constructor_args -}} };
if (FromProto(entry.key(), key)) {
if (FromProto(entry.value(), maybe_value)) {
value = std::move(maybe_value);
}
output.emplace(std::move(key), std::move(value));
} else {
result = false;
break;
}
{%- else %}
{{mojom_key_type}} key{ {{- kind.key_kind|default_constructor_args -}} };
{{mojom_value_type}} value{ {{- kind.value_kind|default_constructor_args -}} };
if (FromProto(entry.key(), key)
&& FromProto(entry.value(), value)) {
output.emplace(std::move(key), std::move(value));
} else {
result = false;
break;
}
{%- endif %}
}
return result;
}{{"\n"-}}
{%- if kind.key_kind|is_array_kind %}
{{define_array(type ~ "Key", kind.key_kind)}}
{%- elif kind.key_kind|is_map_kind %}
{{define_map(type ~ "Key", kind.key_kind)}}
{%- else %}
bool FromProto(
const {{type}}Key& input,
{{mojom_key_type}}& output) {
return FromProto(input.value(), output);
}{{"\n"-}}
{%- endif %}
{%- if kind.value_kind|is_array_kind %}
{{- define_array(type ~ "Value", kind.value_kind)}}
{%- elif kind.value_kind|is_map_kind %}
{{- define_map(type ~ "Value", kind.value_kind)}}
{%- elif kind.value_kind|is_nullable_kind %}
bool FromProto(
const {{type}}Value& input,
{{mojom_maybe_value_type}}& output) {
return FromProto(input.value(), output);
}{{"\n"-}}
{%- else %}
bool FromProto(
const {{type}}Value& input,
{{mojom_value_type}}& output) {
return FromProto(input.value(), output);
}{{"\n"-}}
{%- endif %}
{%- endmacro %}
{%- macro define(parent_name, kind, name) %}
{%- if kind|is_array_kind %}
{%- set array_type = parent_name ~ "::" ~ name|under_to_camel ~ "_Array" %}
{{- define_array(array_type, kind)}}
{%- elif kind|is_map_kind %}
{%- set map_type = parent_name ~ "::" ~ name|under_to_camel ~ "_Map" %}
{{- define_map(map_type, kind)}}
{%- endif %}
{%- endmacro %}
{%- macro define_enum(enum) -%}
{%- set mojom_type = enum|cpp_wrapper_call_type(add_same_module_namespaces=true) %}
{%- set proto_type = "::mojolpm" ~ (enum|get_qualified_name_for_kind(flatten_nested_kind=True)) %}
{%- set enum_type = enum|get_qualified_name_for_kind(flatten_nested_kind=True) %}
bool FromProto(
const {{proto_type}}& input,
{{mojom_type}}& output) {
{%- if enum|is_native_only_kind or not enum|is_typemapped_kind %}
// This ignores IPC_PARAM_TRAITS for native IPC enums, but internal to the
// fuzzer we don't want the overhead of the serialization layer if we don't
// need it. This doesn't change the actual checks on the receiving end.
output = static_cast<{{mojom_type}}>(input);
return true;
{%- else %}
return ::mojo::EnumTraits<{{enum_type}}, {{mojom_type}}>::FromMojom(
static_cast<{{enum_type}}>(input), &output);
{%- endif %}
}
{%- endmacro %}
{%- macro define_struct(struct) -%}
{%- set mojom_type = struct|cpp_wrapper_call_type(add_same_module_namespaces=true) %}
{%- set proto_type = "::mojolpm" ~ (struct|get_qualified_name_for_kind(flatten_nested_kind=True)) %}
{%- set struct_type = proto_type ~ "_ProtoStruct" %}
bool FromProto(
const {{struct_type}}& input,
{{mojom_type}}& output) {
{%- if struct|is_native_only_kind %}
memset((void*)&output, 0, sizeof(output));
if (input.native_bytes().size() < sizeof(output)) {
memcpy((void*)&output, input.native_bytes().data(), input.native_bytes().size());
} else {
memcpy((void*)&output, input.native_bytes().data(), sizeof(output));
}
return true;
{%- elif struct|is_typemapped_kind %}
{%- set dataview_type = (struct|get_qualified_name_for_kind(flatten_nested_kind=True)) ~ "DataView" %}
{%- set data_type = (struct|get_qualified_name_for_kind(flatten_nested_kind=True, internal=True)) %}
::mojo::Message mojolpm_message(0, 0, 0, 0, nullptr);
::mojo::internal::MessageFragment<{{data_type}}> mojolpm_fragment(
mojolpm_message);
bool result = false;
::mojo::internal::Serializer<{{dataview_type}}, const {{struct_type}}>::Serialize(
input, mojolpm_fragment);
result = ::mojo::internal::Serializer<{{dataview_type}}, {{mojom_type}}>::Deserialize(
mojolpm_fragment.data(), &output, &mojolpm_message);
return result;
{%- elif struct.fields %}
bool mojolpm_result = true;
{%- for field in struct.fields %}
{%- set name = field.name|camel_to_under %}
{%- set kind = field.kind %}
{%- set field_mojom_type = kind|cpp_wrapper_type(add_same_module_namespaces=true) %}
{{field_mojom_type}} local_{{name}}{ {{- kind|default_constructor_args -}} };
{%- if kind|is_nullable_kind %}
{%- set unnullable_kind = kind|to_unnullable_kind %}
{%- set field_maybe_mojom_type = unnullable_kind|cpp_wrapper_type(add_same_module_namespaces=true) %}
{{field_maybe_mojom_type}} local_maybe_{{name}}{ {{- unnullable_kind|default_constructor_args -}} };
{%- endif %}
{%- endfor %}
{%- for field in struct.fields -%}
{%- set name = field.name|camel_to_under %}
{%- set kind = field.kind %}
{%- if not kind|is_nullable_kind %}
mojolpm_result &= FromProto(input.m_{{name}}(), local_{{name}});
{%- else %}
if (input.has_m_{{name}}() && FromProto(input.m_{{name}}(), local_maybe_{{name}})) {
local_{{name}} = std::move(local_maybe_{{name}});
}
{%- endif %}
{%- endfor %}
if (mojolpm_result) {
output = {{struct|get_qualified_name_for_kind(flatten_nested_kind=true)}}::New(
{%- for field in struct.fields -%}
{%- set name = field.name|camel_to_under %}
std::move(local_{{name}}){{ ', ' if not loop.last }}
{%- endfor -%});
}
return mojolpm_result;
{%- else %}
output = {{struct|get_qualified_name_for_kind(flatten_nested_kind=true)}}::New();
return true;
{%- endif %}
}
bool FromProto(
const {{proto_type}}& input,
{{mojom_type}}& output) {
if (input.instance_case() == {{proto_type}}::kOld) {
{{struct_type}}* old = mojolpm::GetContext()->GetInstance<{{struct_type}}>(input.old());
if (old) {
return FromProto(*old, output);
}
} else {
return FromProto(input.new_(), output);
}
return false;
}
{%- endmacro %}
{%- macro define_union(union) -%}
{%- set mojom_type = union|cpp_wrapper_call_type(add_same_module_namespaces=true) %}
{%- set proto_type = "::mojolpm" ~ (union|get_qualified_name_for_kind(flatten_nested_kind=True)) %}
{%- set union_type = proto_type ~ "_ProtoUnion" %}
bool FromProto(
const {{union_type}}& input,
{{mojom_type}}& output) {
{%- if union|is_typemapped_kind %}
{%- set dataview_type = (union|get_qualified_name_for_kind(flatten_nested_kind=True)) ~ "DataView" %}
{%- set data_type = (union|get_qualified_name_for_kind(flatten_nested_kind=True, internal=True)) %}
::mojo::Message mojolpm_message(0, 0, 0, 0, nullptr);
::mojo::internal::MessageFragment<{{data_type}}> mojolpm_fragment(
mojolpm_message);
::mojo::internal::Serializer<{{dataview_type}}, const {{union_type}}>::Serialize(
input, mojolpm_fragment, false);
return ::mojo::internal::Serializer<{{dataview_type}}, {{mojom_type}}>::Deserialize(
mojolpm_fragment.data(), &output, &mojolpm_message);
{%- else %}
switch (input.union_member_case()) {
{%- for field in union.fields %}
{%- set name = field.name|camel_to_under %}
{%- set kind = field.kind %}
{%- set field_mojom_type = kind|cpp_wrapper_type(add_same_module_namespaces=true) %}
case {{union_type}}::k{{("m_" ~ name)|under_to_camel}}: {
{%- if kind|is_nullable_kind %}
{%- set unnullable_kind = kind|to_unnullable_kind %}
{%- set field_maybe_mojom_type = unnullable_kind|cpp_wrapper_type(add_same_module_namespaces=true) %}
{{field_mojom_type}} local_{{name}}{ {{- kind|default_constructor_args -}} };
{{field_maybe_mojom_type}} maybe_local_{{name}}{ {{- unnullable_kind|default_constructor_args -}} };
if (FromProto(input.m_{{name}}(), maybe_local_{{name}})) {
local_{{name}} = std::move(maybe_local_{{name}});
}
output = {{union|get_qualified_name_for_kind(flatten_nested_kind=true)}}::New{{name|under_to_camel(digits_split=false)}}(std::move(local_{{name}}));
return true;
{%- else %}
{{field_mojom_type}} local_{{name}}{ {{- kind|default_constructor_args -}} };
if (FromProto(input.m_{{name}}(), local_{{name}})) {
output = {{union|get_qualified_name_for_kind(flatten_nested_kind=true)}}::New{{name|under_to_camel(digits_split=false)}}(std::move(local_{{name}}));
return true;
}
break;
{%- endif %}
}
{% endfor %}
default: {
return false;
}
}
return false;
{%- endif %}
}
bool FromProto(
const {{proto_type}}& input,
{{mojom_type}}& output) {
if (input.instance_case() == {{proto_type}}::kOld) {
{{union_type}}* old = mojolpm::GetContext()->GetInstance<{{union_type}}>(input.old());
if (old) {
return FromProto(*old, output);
}
} else {
return FromProto(input.new_(), output);
}
return false;
}
{%- endmacro -%}