{#---
Macro for enum definition, and the declaration of associated functions.
---#}
{%- macro kythe_annotation(name) %}
{%- if enable_kythe_annotations %}
// @generated_from: {{name}}
{%- endif %}
{%- endmacro %}
{%- macro enum_forward(enum) %}
{%- set enum_name = enum|get_name_for_kind(flatten_nested_kind=True) %}
enum class {{enum_name}} : int32_t;
{%- endmacro %}
{%- macro enum_decl(enum, export_attribute) %}
{%- set enum_name = enum|get_name_for_kind(flatten_nested_kind=True) %}
{%- set full_enum_name = enum|get_full_mojom_name_for_kind() %}
{{ kythe_annotation(full_enum_name) }}
enum class {{enum_name}} : int32_t {
{%- for field in enum.fields %}
{{ kythe_annotation("%s.%s"|format(full_enum_name, field.name)) }}
{{field.name}} = {{field.numeric_value}},
{%- endfor %}
{%- if enum.min_value is not none %}
kMinValue = {{enum.min_value}},
{%- endif %}
{%- if enum.max_value is not none %}
kMaxValue = {{enum.max_value}},
{%- endif %}
{%- if enum.default_field %}
kDefaultValue = {{enum.default_field.numeric_value}}
{%- endif %}
};
{{export_attribute}} std::ostream& operator<<(std::ostream& os, {{enum_name}} value);
{#- Returns true if the given enum value exists in this version of enum. #}
inline bool IsKnownEnumValue({{enum_name}} value) {
return {{enum|get_name_for_kind(internal=True,
flatten_nested_kind=True)}}::IsKnownValue(
static_cast<int32_t>(value));
}
{%- if enum.extensible and enum.default_field %}
inline {{enum_name}} ToKnownEnumValue({{enum_name}} value) {
if (IsKnownEnumValue(value)) {
return value;
}
return {{enum_name}}::kDefaultValue;
}
{%- endif %}
{%- endmacro %}
{%- macro enum_stream(enum) %}
{%- set enum_name = enum|get_name_for_kind(flatten_nested_kind=True) %}
std::ostream& operator<<(std::ostream& os, {{enum_name}} value) {
return os << {{enum_name}}ToString(value);
}
{%- endmacro %}
{%- macro enum_to_string(enum) %}
{%- set enum_name = enum|get_name_for_kind(flatten_nested_kind=True) %}
NOINLINE static const char* {{enum_name}}ToStringHelper({{enum_name}} value) {
// Defined in a helper function to ensure that Clang generates a lookup table.
{%- if enum.fields %}
switch(value) {
{%- for _, values in enum.fields|groupby('numeric_value') %}
case {{enum_name}}::{{values[0].name}}:
return "
{%- if values|length > 1 -%}
{{'{'}}
{%- endif -%}
{{values|map(attribute='name')|join(', ')}}
{%- if values|length > 1 -%}
{{'}'}}
{%- endif -%}
";
{%- endfor %}
default:
return nullptr;
}
{%- else %}
return nullptr;
{%- endif %}
}
std::string {{enum_name}}ToString({{enum_name}} value) {
const char *str = {{enum_name}}ToStringHelper(value);
if (!str) {
return base::StringPrintf("Unknown {{enum_name}} value: %i", static_cast<int32_t>(value));
}
return str;
}
{%- endmacro %}
{%- macro enum_data_decl(enum) %}
{%- set enum_name = enum|get_name_for_kind(flatten_nested_kind=True) %}
struct {{enum_name}}_Data {
public:
static bool constexpr kIsExtensible = {% if enum.extensible %}true{% else %}false{% endif %};
static bool IsKnownValue(int32_t value) {
{%- if enum.fields %}
switch (value) {
{%- for enum_field in enum.fields|groupby('numeric_value') %}
case {{enum_field[0]}}:
{%- endfor %}
return true;
}
{%- endif %}
return false;
}
static bool Validate(int32_t value,
mojo::internal::ValidationContext* validation_context) {
if (kIsExtensible || IsKnownValue(value))
return true;
ReportValidationError(validation_context,
mojo::internal::VALIDATION_ERROR_UNKNOWN_ENUM_VALUE);
return false;
}
};
{%- endmacro %}
{%- macro enum_hash(enum) %}
{%- set enum_name = enum|get_qualified_name_for_kind(
flatten_nested_kind=True) %}
template <>
struct hash<{{enum_name}}>
: public mojo::internal::EnumHashImpl<{{enum_name}}> {};
{%- endmacro %}
{%- macro enum_trace_format_traits_decl(enum, export_attributes) -%}
{%- set enum_name = enum|get_qualified_name_for_kind(
flatten_nested_kind=True) %}
namespace perfetto {
template <>
struct {{export_attribute}} TraceFormatTraits<{{enum_name}}> {
static void WriteIntoTrace(perfetto::TracedValue context, {{enum_name}} value);
};
} // namespace perfetto
{%- endmacro %}
{%- macro enum_trace_format_traits(enum) -%}
{%- set enum_name = enum|get_qualified_name_for_kind(
flatten_nested_kind=True) %}
namespace perfetto {
// static
void TraceFormatTraits<{{enum_name}}>::WriteIntoTrace(
perfetto::TracedValue context, {{enum_name}} value) {
return std::move(context).WriteString({{enum_name}}ToString(value));
}
} // namespace perfetto
{%- endmacro %}endmacro