Source code

Revision control

Copy as Markdown

Other Tools

// -*- mode: C++ -*-
// AUTOGENERATED BY glean_parser. DO NOT EDIT.
{# The rendered source is autogenerated, but this
Jinja2 template is not. Please file bugs! #}
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_Glean{{ options.header_name }}_h
#define mozilla_Glean{{ options.header_name }}_h
{% if all_objs|has_structure %}
#include "mozilla/JSONStringWriteFuncs.h"
{% endif %}
#include "mozilla/glean/bindings/MetricTypes.h"
namespace mozilla::glean {
{%- macro structure_to_json(struct, property_name, value) -%}
{% if struct.type == "array" and property_name %}
if ({{value}}.isSome()) {
writer.StartArrayProperty("{{property_name}}");
{% set valuename = value|replace("->", "")|camelize ~ "Item" %}
for (const auto& {{valuename}}: *{{value}}) {
{{ structure_to_json(struct["items"], None, valuename)|indent(4) }}
}
writer.EndArray();
}
{% elif struct.type == "array" and not property_name %}
writer.StartArrayElement();
{
{% set valuename = value|replace("->", "")|camelize ~ "Item" %}
for (const auto& {{valuename}}: {{value}}) {
{{ structure_to_json(struct["items"], None, valuename)|indent(4) }}
}
}
writer.EndArray();
{% elif struct.type == "object" and property_name %}
if ({{value}}.isSome()) {
writer.StartObjectProperty("{{property_name}}");
{% for propname, val in struct.properties.items() %}
{{ structure_to_json(val, propname, value ~ "->" ~ propname)|indent(2) }}
{%- endfor %}
writer.EndObject();
}
{% elif struct.type == "object" and not property_name %}
writer.StartObjectElement();
{
{% for propname, val in struct.properties.items() %}
{{ structure_to_json(val, propname, value ~ "." ~ propname)|indent(2) }}
{%- endfor %}
}
writer.EndObject();
{% elif property_name %}
if ({{value}}.isSome()) {
writer.{{struct.type|jsonwriter_prefix}}Property("{{property_name}}", *({{value}}));
}
{% else %}
writer.{{struct.type|jsonwriter_prefix}}Element({{value}});
{% endif %}
{%- endmacro -%}
{%- macro generate_structure(name, struct) -%}
{% if struct.type == "array" %}
{% if struct["items"].type not in ("array", "object") %}
using {{ name }} = nsTArray<{{struct["items"].type|structure_type_name}}>;
{% else %}
{{ generate_structure(name ~ "Item", struct["items"]) }}
using {{ name }} = nsTArray<{{ name }}Item>;
{% endif %}
{% elif struct.type == "object" %}
{% for itemname, val in struct.properties.items() %}
{% if val.type in ("array", "object") %}
{{ generate_structure(name ~ itemname|Camelize, val) }}
{% endif %}
{% endfor %}
struct {{ name }} {
{% for itemname, val in struct.properties.items() %}
{% if val.type not in ("array", "object") %}
Maybe<{{val.type|structure_type_name}}> {{ itemname }};
{% else %}
Maybe<{{name ~ itemname|Camelize}}> {{ itemname }};
{% endif %}
{% endfor %}
};
{% endif %}
{%- endmacro -%}
{%- macro generate_extra_keys(obj) -%}
{% for name, suffix in obj["_generate_enums"] %}
{# we always use the `extra` suffix, because we only expose the new event API #}
{% set suffix = "Extra" %}
{% if obj|attr(name)|length %}
{{ extra_keys_with_types(obj, name, suffix)|indent(2) }}
{% endif %}
{% endfor %}
{%- endmacro -%}
{%- macro extra_keys_with_types(obj, name, suffix) -%}
struct {{ obj.name|Camelize }}{{ suffix }} {
{% for item, type in obj|attr(name) %}
mozilla::Maybe<{{type|extra_type_name}}> {{ item|camelize }};
{% endfor %}
std::tuple<nsTArray<nsCString>, nsTArray<nsCString>> ToFfiExtra() const {
nsTArray<nsCString> extraKeys;
nsTArray<nsCString> extraValues;
{% for item, type in obj|attr(name) %}
if ({{item|camelize}}) {
extraKeys.AppendElement()->AssignASCII("{{item}}");
{% if type == "string" %}
extraValues.EmplaceBack({{item|camelize}}.value());
{% elif type == "boolean" %}
extraValues.AppendElement()->AssignASCII({{item|camelize}}.value() ? "true" : "false");
{% elif type == "quantity" %}
extraValues.AppendElement()->AppendInt({{item|camelize}}.value());
{% else %}
#error "Glean: Invalid extra key type for metric {{obj.category}}.{{obj.name}}, defined in: {{obj.defined_in['filepath']}}:{{obj.defined_in['line']}})"
{% endif %}
}
{% endfor %}
return std::make_tuple(std::move(extraKeys), std::move(extraValues));
}
};
{%- endmacro -%}
{# Okay, so though `enum class` means we can't pollute the namespace with the
enum variants' identifiers, there's no guarantee there isn't some
preprocessor #define lying in wait to collide with us. Using CamelCase
helps, but isn't foolproof (X11/X.h has `#define Success 0`).
So we prefix it. I chose `e` (for `enum`) for the prefix. #}
{%- macro generate_label_enum(obj) -%}
enum class {{ obj.name|Camelize }}Label: uint16_t {
{% for label in obj.ordered_labels %}
e{{ label|Camelize }} = {{loop.index0}},
{% endfor %}
e__Other__,
};
{%- endmacro %}
{% for category_name, objs in all_objs.items() %}
namespace {{ category_name|snake_case }} {
{% for obj in objs.values() %}
/**
* generated from {{ category_name }}.{{ obj.name }}
{% if obj|attr("_generate_enums") or (obj.labeled and obj.labels and obj.labels|length) or obj|attr("_generate_structure")%}
*/
{% if obj|attr("_generate_structure") %}
{{ generate_structure(obj.name|Camelize ~ "Object", obj._generate_structure) }}
{%- endif %}
{% if obj|attr("_generate_enums") %}
{{ generate_extra_keys(obj) }}
{%- endif %}
{% if obj.labeled and obj.labels and obj.labels|length %}
{{ generate_label_enum(obj)|indent(2) }}
{% endif %}
/**
{% endif %}
* {{ obj.description|trim | replace('\n', '\n * ') }}
*/
constexpr impl::{{ obj|type_name }} {{obj.name|snake_case }}({{obj|metric_id}});
{% if not loop.last %}
{% endif %}
{% endfor %}
}
{% for obj in objs.values() %}
{% if obj|attr("_generate_structure") %}
{% set typename_t = category_name|snake_case ~ "::" ~ obj.name|Camelize ~ "Object" %}
template <>
inline void impl::ObjectMetric<{{typename_t}}, {{typename_t}}Tag>::Set(const {{typename_t}}& aObj) const {
nsCString json;
JSONStringRefWriteFunc writeFunc(json);
JSONWriter writer(writeFunc, JSONWriter::CollectionStyle::SingleLineStyle);
{{ structure_to_json(obj._generate_structure, None, "aObj")|indent(2) }}
SetStr(json);
}
{% endif %}
{% endfor %}
{% endfor %}
} // namespace mozilla::glean
#endif // mozilla_Glean{{ options.header_name }}_h