// -*- 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_Metrics_h #define mozilla_Metrics_h #include "mozilla/glean/bindings/MetricTypes.h" #include "mozilla/Maybe.h" #include "nsTArray.h" #include "nsPrintfCString.h" #include namespace mozilla::glean { {%- 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 }} {% 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> ToFfiExtra() const { nsTArray extraKeys; nsTArray 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.EmplaceBack(nsPrintfCString("%d", {{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 %} struct NoExtraKeys; enum class DynamicLabel: uint16_t { }; {% for category_name, objs in all_objs.items() %} namespace {{ category_name|snake_case }} { {% for obj in objs.values() %} {% if obj.type != "object" %}{# TODO(bug 1881023): Add C++ support #} /** * generated from {{ category_name }}.{{ obj.name }} */ {% 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 }} {% endif %} /** * {{ obj.description|wordwrap() | replace('\n', '\n * ') }} */ constexpr impl::{{ obj|type_name }} {{obj.name|snake_case }}({{obj|metric_id}}); {% endif %} {% endfor %} } {% endfor %} } // namespace mozilla::glean #endif // mozilla_Metrics_h