summaryrefslogtreecommitdiffstats
path: root/third_party/python/glean_parser
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/python/glean_parser')
-rw-r--r--third_party/python/glean_parser/glean_parser-14.0.1.dist-info/AUTHORS.md (renamed from third_party/python/glean_parser/glean_parser-13.0.1.dist-info/AUTHORS.md)0
-rw-r--r--third_party/python/glean_parser/glean_parser-14.0.1.dist-info/LICENSE (renamed from third_party/python/glean_parser/glean_parser-13.0.1.dist-info/LICENSE)0
-rw-r--r--third_party/python/glean_parser/glean_parser-14.0.1.dist-info/METADATA (renamed from third_party/python/glean_parser/glean_parser-13.0.1.dist-info/METADATA)15
-rw-r--r--third_party/python/glean_parser/glean_parser-14.0.1.dist-info/RECORD (renamed from third_party/python/glean_parser/glean_parser-13.0.1.dist-info/RECORD)36
-rw-r--r--third_party/python/glean_parser/glean_parser-14.0.1.dist-info/WHEEL (renamed from third_party/python/glean_parser/glean_parser-13.0.1.dist-info/WHEEL)0
-rw-r--r--third_party/python/glean_parser/glean_parser-14.0.1.dist-info/entry_points.txt (renamed from third_party/python/glean_parser/glean_parser-13.0.1.dist-info/entry_points.txt)0
-rw-r--r--third_party/python/glean_parser/glean_parser-14.0.1.dist-info/top_level.txt (renamed from third_party/python/glean_parser/glean_parser-13.0.1.dist-info/top_level.txt)0
-rw-r--r--third_party/python/glean_parser/glean_parser/javascript_server.py16
-rw-r--r--third_party/python/glean_parser/glean_parser/kotlin.py25
-rw-r--r--third_party/python/glean_parser/glean_parser/parser.py24
-rw-r--r--third_party/python/glean_parser/glean_parser/pings.py6
-rw-r--r--third_party/python/glean_parser/glean_parser/schemas/pings.2-0-0.schema.yaml22
-rw-r--r--third_party/python/glean_parser/glean_parser/swift.py23
-rw-r--r--third_party/python/glean_parser/glean_parser/templates/javascript_server.jinja254
-rw-r--r--third_party/python/glean_parser/glean_parser/templates/kotlin.jinja266
-rw-r--r--third_party/python/glean_parser/glean_parser/templates/rust.jinja22
-rw-r--r--third_party/python/glean_parser/glean_parser/templates/swift.jinja249
-rw-r--r--third_party/python/glean_parser/glean_parser/util.py2
18 files changed, 284 insertions, 56 deletions
diff --git a/third_party/python/glean_parser/glean_parser-13.0.1.dist-info/AUTHORS.md b/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/AUTHORS.md
index 525116ee7e..525116ee7e 100644
--- a/third_party/python/glean_parser/glean_parser-13.0.1.dist-info/AUTHORS.md
+++ b/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/AUTHORS.md
diff --git a/third_party/python/glean_parser/glean_parser-13.0.1.dist-info/LICENSE b/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/LICENSE
index a612ad9813..a612ad9813 100644
--- a/third_party/python/glean_parser/glean_parser-13.0.1.dist-info/LICENSE
+++ b/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/LICENSE
diff --git a/third_party/python/glean_parser/glean_parser-13.0.1.dist-info/METADATA b/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/METADATA
index 0bab2150ba..65030fd86b 100644
--- a/third_party/python/glean_parser/glean_parser-13.0.1.dist-info/METADATA
+++ b/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
-Name: glean-parser
-Version: 13.0.1
+Name: glean_parser
+Version: 14.0.1
Summary: Parser tools for Mozilla's Glean telemetry
Home-page: https://github.com/mozilla/glean_parser
Author: The Glean Team
@@ -77,7 +77,16 @@ $ glean_parser check < ping.json
# Changelog
-## Unreleased
+## 14.0.1
+
+- BUGFIX: Fix missing `ping_arg` in util.py ([#687](https://github.com/mozilla/glean_parser/pull/687))
+
+## 14.0.0
+
+- BREAKING CHANGE: Expose the optional `enabled` property on pings, defaulting to `enabled: true` ([#681](https://github.com/mozilla/glean_parser/pull/681))
+- BREAKING CHANGE: Support metadata field `ping_schedule` for pings ([bug 1804711](https://bugzilla.mozilla.org/show_bug.cgi?id=1804711))
+- Add support for event metric type in server JavaScript outputter ([DENG-2407](https://mozilla-hub.atlassian.net/browse/DENG-2407))
+- Add Swift and Kotlin codegen support for the object metric type object ([#685](https://github.com/mozilla/glean_parser/pull/685))
## 13.0.1
diff --git a/third_party/python/glean_parser/glean_parser-13.0.1.dist-info/RECORD b/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/RECORD
index 8ebf523fd7..700ca80797 100644
--- a/third_party/python/glean_parser/glean_parser-13.0.1.dist-info/RECORD
+++ b/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/RECORD
@@ -4,45 +4,45 @@ glean_parser/coverage.py,sha256=2IwC4XMDtDamMkBFoYilmqJzW4gyypq65YVCur8SNas,4405
glean_parser/data_review.py,sha256=BweeeTkNNS6HrIDkztawhbDByrk_-Avxpg7YeST3VAs,2152
glean_parser/go_server.py,sha256=s6lxK9IAFY55pNl3Rv4MHlV-nQwSoyhO9ppTQE9VCik,5346
glean_parser/javascript.py,sha256=w4ZhNBHBKWYk0h3t7G0Ud2tR__hRqzn9dlEXNKLdQrA,11230
-glean_parser/javascript_server.py,sha256=x75JfOaveEkPQe3ozYXdtDb1Zks-PxzncDOizsJbYos,7972
-glean_parser/kotlin.py,sha256=5z8_74xlqvHDsedwZhGf1_qb7swPEgIZumkJIuj3ef8,12598
+glean_parser/javascript_server.py,sha256=PZSTl63TR3cY8Y99jXMOLu-8rzgQarymzjnHJm9aYK0,8389
+glean_parser/kotlin.py,sha256=5nXnen4s2YOj503Z77HVTUgDHWdulB8BMl8vOie38o4,13365
glean_parser/lint.py,sha256=STqdgyOhR4Q3fHivSizgn9bOOyqrNHhzjaqyJxz6qzI,19948
glean_parser/markdown.py,sha256=GkCr1CrV6mnRQseT6FO1-JJ7Eup8X3lxUfRMBTxXpe4,9066
glean_parser/metrics.py,sha256=YAO8wPuRHTLkdT9M4zh9ZwoFI1_VS8O9oQqwZNYyDp0,14612
-glean_parser/parser.py,sha256=cUOnvSXKfEBg8YTpRcWiPcMwpFpK1TTqsVO_zjUtpR4,15309
-glean_parser/pings.py,sha256=AQ-fBmIx2GKQv6J2NyTFfHHZzSnApZZoC770LlstkoI,3180
+glean_parser/parser.py,sha256=3-uF-Hi5LlvdFc1NxZOKX0EoEyekZGnZV094eTIJut0,16361
+glean_parser/pings.py,sha256=-CIiMBVOTFULmNybV8YTFI7vmfOYOGQ5TD9hEfYPUII,3435
glean_parser/python_server.py,sha256=ERpYcbSwF19xKFagxX0mZAvlR1y6D7Ah5DSvW8LipCY,4791
glean_parser/ruby_server.py,sha256=e5lkfcLQAUMUBQDCjqNU82LkdUzT5x-G6HOnsUInbsU,5190
glean_parser/rust.py,sha256=UEHeIZlToxCBelfec5sl_l_uLZfk8f_OUXqa_ZoEvnk,7330
-glean_parser/swift.py,sha256=T1BSGahd9wUd6VDeNC89SdN6M34jKXDlydMpSI0QLOs,8379
+glean_parser/swift.py,sha256=paUzF6tItdktFwIQYCKsYpqXfn8zxR2coU_jMYrmwlc,8957
glean_parser/tags.py,sha256=bemKYvcbMO4JrghiNSe-A4BNNDtx_FlUPkgrPPJy84Y,1391
glean_parser/translate.py,sha256=luKQoraARZ2tjenHs0SVtCxflnYaMkzPYFfKEdKdSqQ,8403
glean_parser/translation_options.py,sha256=Lxzr6G7MP0tC_ZYlZXftS4j0SLiqO-5mGVTEc7ggXis,2037
-glean_parser/util.py,sha256=v81watw5nSPGRlFNNpTb7iUv9NZObiFIbyyg2oZ6EnY,16149
+glean_parser/util.py,sha256=wftmoWBUQM_o7pUwdhBp3HuDCVHIBw1PXtrfxwPLD0Q,16187
glean_parser/validate_ping.py,sha256=0TNvILH6dtzJDys3W8Kqorw6kk03me73OCUDtpoHcXU,2118
glean_parser/schemas/metrics.1-0-0.schema.yaml,sha256=cND3cvi6iBfPUVmtfIBQfGJV9AALpbvN7nu8E33_J-o,19566
glean_parser/schemas/metrics.2-0-0.schema.yaml,sha256=wx1q0L4C0-Vcwk1SPU6t8OfjDEQvgrwwEG6xfSHO1MI,26365
glean_parser/schemas/pings.1-0-0.schema.yaml,sha256=hwCnsKpEysmrmVp-QHGBArEkVY3vaU1rVsxlTwhAzws,4315
-glean_parser/schemas/pings.2-0-0.schema.yaml,sha256=vDyvFT8KwAwaqyWHG4y6pFNrsc3NO7OyDDagA2eTeqM,5415
+glean_parser/schemas/pings.2-0-0.schema.yaml,sha256=f8PClAlMoLTmX6ANq8Ai0CpiE74i3LOgU5SoTJpoh0M,6149
glean_parser/schemas/tags.1-0-0.schema.yaml,sha256=OGXIJlvvVW1vaqB_NVZnwKeZ-sLlfH57vjBSHbj6DNI,1231
glean_parser/templates/data_review.jinja2,sha256=jeYU29T1zLSyu9fKBBFu5BFPfIw8_hmOUXw8RXhRXK8,3287
glean_parser/templates/go_server.jinja2,sha256=Jy1e0uQqr_WZNoj-AWnygRmygX2jyj_GQMMV8mSah2k,6825
glean_parser/templates/javascript.buildinfo.jinja2,sha256=4mXiZCQIk9if4lxlA05kpSIL4a95IdwGwqle2OqqNAs,474
glean_parser/templates/javascript.jinja2,sha256=cT_bG-jC6m4afECXmcsqHwiiHjRuVtJnfv90OD2Mwxw,2669
-glean_parser/templates/javascript_server.jinja2,sha256=H991yQOKJMwSgM0bLEA-Q5Z15LWsfEPh6bTYz_owSCU,9423
+glean_parser/templates/javascript_server.jinja2,sha256=k-XI3QIhHQ1vbIPqSMTmCu93b1oZhm7KLmx9LfO3IJ0,9472
glean_parser/templates/kotlin.buildinfo.jinja2,sha256=X0lk2SNu5OIIj2i6mUyF9CWFQIonLgfqkgT5fA-5G6c,920
glean_parser/templates/kotlin.geckoview.jinja2,sha256=MJOgtoDXmBjE9pwk-G6T89y36RZuMbDWM_-DBN_gFJo,5099
-glean_parser/templates/kotlin.jinja2,sha256=3DqUMXJRkmTvSp_5IRyvGmw5iXYWdox7coMFe3YDxcc,5247
+glean_parser/templates/kotlin.jinja2,sha256=npMgDdWD9OItOZQ-dyLQZn_IKgnzee2EdJynhUa1ig8,7690
glean_parser/templates/markdown.jinja2,sha256=vAHHGGm28HRDPd3zO_wQMAUZIuxE9uQ7hl3NpXxcKV4,3425
glean_parser/templates/python_server.jinja2,sha256=gu2C1rkn760IqBCG2SWaK7o32T1ify94wDEsudLPUg8,7260
glean_parser/templates/qmldir.jinja2,sha256=m6IGsp-tgTiOfQ7VN8XW6GqX0gJqJkt3B6Pkaul6FVo,156
glean_parser/templates/ruby_server.jinja2,sha256=vm4BEenOqzomQNTLFfMOzlWHARnsWUjTBbnR-v2cadI,6247
-glean_parser/templates/rust.jinja2,sha256=wlV0OZvV3Mk2ulrqFkN1vGjdsahsupEy2TQvWxQKzww,5439
-glean_parser/templates/swift.jinja2,sha256=xkvVsTpfK0QK3tI32wGqzxm2hqFNaBQ6Y71rKIsCmAI,4944
-glean_parser-13.0.1.dist-info/AUTHORS.md,sha256=yxgj8MioO4wUnrh0gmfb8l3DJJrf-l4HmmEDbQsbbNI,455
-glean_parser-13.0.1.dist-info/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
-glean_parser-13.0.1.dist-info/METADATA,sha256=UYz6ZRXyv3ODi3yl2vRQHZVdm0XGerFp8pIOGWGwOKw,31604
-glean_parser-13.0.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
-glean_parser-13.0.1.dist-info/entry_points.txt,sha256=mf9d3sv8BwSjjR58x9KDnpVkONCnv3fPQC2NjJl15Xg,68
-glean_parser-13.0.1.dist-info/top_level.txt,sha256=q7T3duD-9tYZFyDry6Wv2LcdMsK2jGnzdDFhxWcT2Z8,13
-glean_parser-13.0.1.dist-info/RECORD,,
+glean_parser/templates/rust.jinja2,sha256=Ir_JqWRIUs1KLoYNDolgTRjWfWdzzBfouCP-YeTJa-c,5495
+glean_parser/templates/swift.jinja2,sha256=4f993l_zZk_Tz1efiz3nbvDK1H3Uq3dWQ2T6glT9XQ4,6695
+glean_parser-14.0.1.dist-info/AUTHORS.md,sha256=yxgj8MioO4wUnrh0gmfb8l3DJJrf-l4HmmEDbQsbbNI,455
+glean_parser-14.0.1.dist-info/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
+glean_parser-14.0.1.dist-info/METADATA,sha256=Ghvw-Y7woQUJ38P8TYT5TFt8sL61GJoZPBajaB0WLeQ,32276
+glean_parser-14.0.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
+glean_parser-14.0.1.dist-info/entry_points.txt,sha256=mf9d3sv8BwSjjR58x9KDnpVkONCnv3fPQC2NjJl15Xg,68
+glean_parser-14.0.1.dist-info/top_level.txt,sha256=q7T3duD-9tYZFyDry6Wv2LcdMsK2jGnzdDFhxWcT2Z8,13
+glean_parser-14.0.1.dist-info/RECORD,,
diff --git a/third_party/python/glean_parser/glean_parser-13.0.1.dist-info/WHEEL b/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/WHEEL
index bab98d6758..bab98d6758 100644
--- a/third_party/python/glean_parser/glean_parser-13.0.1.dist-info/WHEEL
+++ b/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/WHEEL
diff --git a/third_party/python/glean_parser/glean_parser-13.0.1.dist-info/entry_points.txt b/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/entry_points.txt
index 08fde9d655..08fde9d655 100644
--- a/third_party/python/glean_parser/glean_parser-13.0.1.dist-info/entry_points.txt
+++ b/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/entry_points.txt
diff --git a/third_party/python/glean_parser/glean_parser-13.0.1.dist-info/top_level.txt b/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/top_level.txt
index a7f3a37918..a7f3a37918 100644
--- a/third_party/python/glean_parser/glean_parser-13.0.1.dist-info/top_level.txt
+++ b/third_party/python/glean_parser/glean_parser-14.0.1.dist-info/top_level.txt
diff --git a/third_party/python/glean_parser/glean_parser/javascript_server.py b/third_party/python/glean_parser/glean_parser/javascript_server.py
index f5099d2660..060575f38c 100644
--- a/third_party/python/glean_parser/glean_parser/javascript_server.py
+++ b/third_party/python/glean_parser/glean_parser/javascript_server.py
@@ -42,9 +42,12 @@ from . import util
SUPPORTED_METRIC_TYPES = ["string", "event"]
-def event_class_name(ping_name: str, event_metric_exists: bool) -> str:
+def event_class_name(
+ ping_name: str, metrics_by_type: Dict[str, List[metrics.Metric]]
+) -> str:
# For compatibility with FxA codebase we don't want to add "Logger" suffix
# when custom pings without event metrics are used.
+ event_metric_exists = "event" in metrics_by_type
suffix = "Logger" if event_metric_exists else ""
return util.Camelize(ping_name) + "ServerEvent" + suffix
@@ -61,10 +64,13 @@ def generate_js_metric_type(metric: metrics.Metric) -> str:
return metric.type
-def generate_ping_factory_method(ping: str, event_metric_exists: bool) -> str:
+def generate_ping_factory_method(
+ ping: str, metrics_by_type: Dict[str, List[metrics.Metric]]
+) -> str:
# `ServerEventLogger` better describes role of the class that this factory
# method generates, but for compatibility with existing FxA codebase
# we use `Event` suffix if no event metrics are defined.
+ event_metric_exists = "event" in metrics_by_type
suffix = "ServerEventLogger" if event_metric_exists else "Event"
return f"create{util.Camelize(ping)}{suffix}"
@@ -136,6 +142,12 @@ def output(
metrics_list = metrics_by_type.setdefault(metric.type, [])
metrics_list.append(metric)
+ # Order pings_to_metrics for backwards compatibility with the existing FxA codebase.
+ # Put pings without `event` type metrics first.
+ ping_to_metrics = dict(
+ sorted(ping_to_metrics.items(), key=lambda item: "event" in item[1])
+ )
+
PING_METRIC_ERROR_MSG = (
" Server-side environment is simplified and this"
+ " parser doesn't generate individual metric files. Make sure to pass all"
diff --git a/third_party/python/glean_parser/glean_parser/kotlin.py b/third_party/python/glean_parser/glean_parser/kotlin.py
index 82cc63d237..6d9ea8dcf8 100644
--- a/third_party/python/glean_parser/glean_parser/kotlin.py
+++ b/third_party/python/glean_parser/glean_parser/kotlin.py
@@ -107,6 +107,11 @@ def type_name(obj: Union[metrics.Metric, pings.Ping]) -> str:
return "{}<{}>".format(class_name(obj.type), generic)
+ generate_structure = getattr(obj, "_generate_structure", [])
+ if len(generate_structure):
+ generic = util.Camelize(obj.name) + "Object"
+ return "{}<{}>".format(class_name(obj.type), generic)
+
return class_name(obj.type)
@@ -125,6 +130,21 @@ def extra_type_name(typ: str) -> str:
return "UNSUPPORTED"
+def structure_type_name(typ: str) -> str:
+ """
+ Returns the corresponding Kotlin type for structure items.
+ """
+
+ if typ == "boolean":
+ return "Boolean"
+ elif typ == "string":
+ return "String"
+ elif typ == "number":
+ return "Int"
+ else:
+ return "UNSUPPORTED"
+
+
def class_name(obj_type: str) -> str:
"""
Returns the Kotlin class name for a given metric or ping type.
@@ -320,6 +340,7 @@ def output_kotlin(
("type_name", type_name),
("extra_type_name", extra_type_name),
("class_name", class_name),
+ ("structure_type_name", structure_type_name),
),
)
@@ -333,6 +354,9 @@ def output_kotlin(
has_labeled_metrics = any(
getattr(metric, "labeled", False) for metric in category_val.values()
)
+ has_object_metrics = any(
+ isinstance(metric, metrics.Object) for metric in category_val.values()
+ )
with filepath.open("w", encoding="utf-8") as fd:
fd.write(
@@ -346,6 +370,7 @@ def output_kotlin(
ping_args=util.ping_args,
namespace=namespace,
has_labeled_metrics=has_labeled_metrics,
+ has_object_metrics=has_object_metrics,
glean_namespace=glean_namespace,
)
)
diff --git a/third_party/python/glean_parser/glean_parser/parser.py b/third_party/python/glean_parser/glean_parser/parser.py
index 5ca584ac1e..158676be73 100644
--- a/third_party/python/glean_parser/glean_parser/parser.py
+++ b/third_party/python/glean_parser/glean_parser/parser.py
@@ -11,7 +11,7 @@ Code for parsing metrics.yaml files.
import functools
from pathlib import Path
import textwrap
-from typing import Any, Dict, Generator, Iterable, Optional, Tuple, Union
+from typing import Any, cast, Dict, Generator, Iterable, Optional, Set, Tuple, Union
import jsonschema # type: ignore
from jsonschema.exceptions import ValidationError # type: ignore
@@ -267,6 +267,7 @@ def _instantiate_pings(
"""
global_no_lint = content.get("no_lint", [])
assert isinstance(global_no_lint, list)
+ ping_schedule_reverse_map: Dict[str, Set[str]] = dict()
for ping_key, ping_val in sorted(content.items()):
if ping_key.startswith("$"):
@@ -284,6 +285,22 @@ def _instantiate_pings(
if not isinstance(ping_val, dict):
raise TypeError(f"Invalid content for ping {ping_key}")
ping_val["name"] = ping_key
+
+ if "metadata" in ping_val and "ping_schedule" in ping_val["metadata"]:
+ if ping_key in ping_val["metadata"]["ping_schedule"]:
+ yield util.format_error(
+ filepath,
+ f"For ping '{ping_key}'",
+ "ping_schedule contains its own ping name",
+ )
+ continue
+ for ping_schedule in ping_val["metadata"]["ping_schedule"]:
+ if ping_schedule not in ping_schedule_reverse_map:
+ ping_schedule_reverse_map[ping_schedule] = set()
+ ping_schedule_reverse_map[ping_schedule].add(ping_key)
+
+ del ping_val["metadata"]["ping_schedule"]
+
try:
ping_obj = Ping(
defined_in=getattr(ping_val, "defined_in", None),
@@ -313,6 +330,11 @@ def _instantiate_pings(
all_objects.setdefault("pings", {})[ping_key] = ping_obj
sources[ping_key] = filepath
+ for scheduler, scheduled in ping_schedule_reverse_map.items():
+ if isinstance(all_objects["pings"][scheduler], Ping):
+ scheduler_obj: Ping = cast(Ping, all_objects["pings"][scheduler])
+ scheduler_obj.schedules_pings = sorted(list(scheduled))
+
def _instantiate_tags(
all_objects: ObjectTree,
diff --git a/third_party/python/glean_parser/glean_parser/pings.py b/third_party/python/glean_parser/glean_parser/pings.py
index b4145ea68d..b3f2476c9a 100644
--- a/third_party/python/glean_parser/glean_parser/pings.py
+++ b/third_party/python/glean_parser/glean_parser/pings.py
@@ -31,6 +31,7 @@ class Ping:
reasons: Optional[Dict[str, str]] = None,
defined_in: Optional[Dict] = None,
no_lint: Optional[List[str]] = None,
+ enabled: Optional[bool] = None,
_validated: bool = False,
):
# Avoid cyclical import
@@ -46,6 +47,10 @@ class Ping:
self.metadata = metadata
self.precise_timestamps = self.metadata.get("precise_timestamps", True)
self.include_info_sections = self.metadata.get("include_info_sections", True)
+ if enabled is None:
+ enabled = True
+ self.enabled = enabled
+ self.schedules_pings: List[str] = []
if data_reviews is None:
data_reviews = []
self.data_reviews = data_reviews
@@ -94,6 +99,7 @@ class Ping:
modified_dict = util.remove_output_params(
modified_dict, "include_info_sections"
)
+ modified_dict = util.remove_output_params(modified_dict, "schedules_pings")
return modified_dict
def identifier(self) -> str:
diff --git a/third_party/python/glean_parser/glean_parser/schemas/pings.2-0-0.schema.yaml b/third_party/python/glean_parser/glean_parser/schemas/pings.2-0-0.schema.yaml
index 6679a8066b..345812c805 100644
--- a/third_party/python/glean_parser/glean_parser/schemas/pings.2-0-0.schema.yaml
+++ b/third_party/python/glean_parser/glean_parser/schemas/pings.2-0-0.schema.yaml
@@ -96,6 +96,16 @@ additionalProperties:
Interaction with `include_client_id`: `include_client_id` only takes
effect when `metadata.include_info_sections` is `true`.
type: boolean
+ ping_schedule:
+ title: Ping Schedule
+ description: |
+ An optional array of ping names. When one of the listed pings is
+ sent, then this ping will also be sent. A ping cannot list its own
+ name in `ping_schedule`.
+ type: array
+ items:
+ type: string
+ maxLength: 30
default: {}
@@ -175,6 +185,18 @@ additionalProperties:
additionalProperties:
type: string
+ enabled:
+ title: Whether or not this ping is enabled
+ description: |
+ **Optional.**
+
+ When `true`, the ping will be sent as usual.
+ When `false`, the ping will not be sent, but the data will continue to
+ be collected but will not be cleared when the ping is submitted.
+
+ Defaults to `true` if omitted.
+ type: boolean
+
no_lint:
title: Lint checks to skip
description: |
diff --git a/third_party/python/glean_parser/glean_parser/swift.py b/third_party/python/glean_parser/glean_parser/swift.py
index c745c4d9ac..b121933b0f 100644
--- a/third_party/python/glean_parser/glean_parser/swift.py
+++ b/third_party/python/glean_parser/glean_parser/swift.py
@@ -106,12 +106,17 @@ def type_name(obj: Union[metrics.Metric, pings.Ping]) -> str:
return "{}<{}>".format(class_name(obj.type), generic)
+ generate_structure = getattr(obj, "_generate_structure", [])
+ if len(generate_structure):
+ generic = util.Camelize(obj.name) + "Object"
+ return "{}<{}>".format(class_name(obj.type), generic)
+
return class_name(obj.type)
def extra_type_name(typ: str) -> str:
"""
- Returns the corresponding Kotlin type for event's extra key types.
+ Returns the corresponding Swift type for event's extra key types.
"""
if typ == "boolean":
@@ -124,6 +129,21 @@ def extra_type_name(typ: str) -> str:
return "UNSUPPORTED"
+def structure_type_name(typ: str) -> str:
+ """
+ Returns the corresponding Swift type for structure items.
+ """
+
+ if typ == "boolean":
+ return "Bool"
+ elif typ == "string":
+ return "String"
+ elif typ == "number":
+ return "Int64"
+ else:
+ return "UNSUPPORTED"
+
+
def class_name(obj_type: str) -> str:
"""
Returns the Swift class name for a given metric or ping type.
@@ -215,6 +235,7 @@ def output_swift(
("class_name", class_name),
("variable_name", variable_name),
("extra_type_name", extra_type_name),
+ ("structure_type_name", structure_type_name),
),
)
diff --git a/third_party/python/glean_parser/glean_parser/templates/javascript_server.jinja2 b/third_party/python/glean_parser/glean_parser/templates/javascript_server.jinja2
index 0a89f081f6..9df299fd2b 100644
--- a/third_party/python/glean_parser/glean_parser/templates/javascript_server.jinja2
+++ b/third_party/python/glean_parser/glean_parser/templates/javascript_server.jinja2
@@ -21,7 +21,7 @@ type LoggerOptions = { app: string; fmt?: 'heka' };
type Event = {
category: string;
name: string;
- extra: Record<string, any>;
+ extra?: Record<string, any>;
timestamp?: number;
};
{% endif %}
@@ -30,14 +30,14 @@ type Event = {
let _logger{% if lang == "typescript" %}: Logger{% endif %};
{% for ping, metrics_by_type in pings.items() %}
-class {{ ping|event_class_name(event_metric_exists) }} {
+class {{ ping|event_class_name(metrics_by_type) }} {
{% if lang == "typescript" %}
_applicationId: string;
_appDisplayVersion: string;
_channel: string;
{% endif %}
/**
- * Create {{ ping|event_class_name(event_metric_exists) }} instance.
+ * Create {{ ping|event_class_name(metrics_by_type) }} instance.
*
* @param {string} applicationId - The application ID.
* @param {string} appDisplayVersion - The application display version.
@@ -72,7 +72,7 @@ class {{ ping|event_class_name(event_metric_exists) }} {
{% endif %}
}
}
- {% if event_metric_exists %}
+ {% if 'event' in metrics_by_type %}
#record({
{% else %}
/**
@@ -99,28 +99,28 @@ class {{ ping|event_class_name(event_metric_exists) }} {
{% endfor %}
{% endif %}
{% endfor %}
- {% if event_metric_exists %}
+ {% if 'event' in metrics_by_type %}
event,
{% endif %}
{% if lang == "typescript" %}
}: {
- user_agent: string,
- ip_address: string,
+ user_agent: string;
+ ip_address: string;
{% for metric_type, metrics in metrics_by_type.items() %}
{% if metric_type != 'event' %}
{% for metric in metrics %}
- {{ metric|metric_argument_name }}: {{ metric|js_metric_type }},
+ {{ metric|metric_argument_name }}: {{ metric|js_metric_type }};
{% endfor %}
{% endif %}
{% endfor %}
- {% if event_metric_exists %}
- event: Event
+ {% if 'event' in metrics_by_type %}
+ event: Event;
{% endif %}
{% endif %}
}) {
const now = new Date();
const timestamp = now.toISOString();
- {% if event_metric_exists %}
+ {% if 'event' in metrics_by_type %}
event.timestamp = now.getTime();
{% endif %}
const eventPayload = {
@@ -135,7 +135,7 @@ class {{ ping|event_class_name(event_metric_exists) }} {
{% endif %}
{% endfor %}
},
- {% if event_metric_exists %}
+ {% if 'event' in metrics_by_type %}
events: [event],
{% endif %}
ping_info: {
@@ -171,7 +171,7 @@ class {{ ping|event_class_name(event_metric_exists) }} {
// this is similar to how FxA currently logs with mozlog: https://github.com/mozilla/fxa/blob/4c5c702a7fcbf6f8c6b1f175e9172cdd21471eac/packages/fxa-auth-server/lib/log.js#L289
_logger.info(GLEAN_EVENT_MOZLOG_TYPE, ping);
}
- {% if event_metric_exists %}
+ {% if 'event' in metrics_by_type %}
{% for event in metrics_by_type["event"] %}
/**
* Record and submit a {{ event.category }}_{{ event.name }} event:
@@ -209,27 +209,27 @@ class {{ ping|event_class_name(event_metric_exists) }} {
{% endfor %}
{% if lang == "typescript" %}
}: {
- user_agent: string,
- ip_address: string,
+ user_agent: string;
+ ip_address: string;
{% for metric_type, metrics in metrics_by_type.items() %}
{% if metric_type != 'event' %}
{% for metric in metrics %}
- {{ metric|metric_argument_name }}: {{ metric|js_metric_type }},
+ {{ metric|metric_argument_name }}: {{ metric|js_metric_type }};
{% endfor %}
{% endif %}
{% endfor %}
{% for extra, metadata in event.extra_keys.items() %}
- {{ extra }}: {{metadata.type}},
+ {{ extra }}: {{metadata.type}};
{% endfor %}
{% endif %}
}) {
- let event = {
- 'category': '{{ event.category }}',
- 'name': '{{ event.name }}',
+ const event = {
+ category: '{{ event.category }}',
+ name: '{{ event.name }}',
{% if event.extra_keys %}
- 'extra': {
+ extra: {
{% for extra, metadata in event.extra_keys.items() %}
- '{{ extra }}': {{ extra }},
+ {{ extra }}: {{ extra }},
{% endfor %}
},
{% endif %}
@@ -244,14 +244,14 @@ class {{ ping|event_class_name(event_metric_exists) }} {
{% endfor %}
{% endif %}
{% endfor %}
- event
+ event,
});
}
{% endfor %}
{% endif %}
}
{% endfor %}
-{% for ping in pings %}
+{% for ping, metrics_by_type in pings.items() %}
/**
* Factory function that creates an instance of Glean Server Event Logger to
@@ -262,11 +262,11 @@ class {{ ping|event_class_name(event_metric_exists) }} {
* @param {Object} logger_options - The logger options.
* @returns {EventsServerEventLogger} An instance of EventsServerEventLogger.
*/
-export const {{ ping|factory_method(event_metric_exists) }} = function ({
+export const {{ ping|factory_method(metrics_by_type) }} = function ({
applicationId,
appDisplayVersion,
channel,
- logger_options
+ logger_options,
{% if lang == "typescript" %}
}: {
applicationId: string;
@@ -275,7 +275,7 @@ export const {{ ping|factory_method(event_metric_exists) }} = function ({
logger_options: LoggerOptions;
{% endif %}
}) {
- return new {{ ping|event_class_name(event_metric_exists) }}(
+ return new {{ ping|event_class_name(metrics_by_type) }}(
applicationId,
appDisplayVersion,
channel,
diff --git a/third_party/python/glean_parser/glean_parser/templates/kotlin.jinja2 b/third_party/python/glean_parser/glean_parser/templates/kotlin.jinja2
index bd800af01d..71ba386a4c 100644
--- a/third_party/python/glean_parser/glean_parser/templates/kotlin.jinja2
+++ b/third_party/python/glean_parser/glean_parser/templates/kotlin.jinja2
@@ -66,6 +66,61 @@ data class {{ obj.name|Camelize }}{{ suffix }}(
}
{%- endmacro -%}
+{%- macro generate_structure(name, struct) %}
+{%- if struct.type == "array" -%}
+ @Serializable
+ data class {{ name }}(var items: MutableList<{{ name }}Item> = mutableListOf()) : ObjectSerialize {
+ fun add(elem: {{ name }}Item) = items.add(elem)
+
+ fun addAll(elements: Collection<{{ name }}Item>) = items.addAll(elements)
+
+ fun clear() = items.clear()
+
+ fun remove(element: {{ name }}Item) = items.remove(element)
+ fun removeAll(elements: Collection<{{ name }}Item>) = items.removeAll(elements)
+ fun removeAt(index: Int) = items.removeAt(index)
+
+ fun set(index: Int, element: {{ name }}Item) = items.set(index, element)
+
+ override fun intoSerializedObject(): String {
+ return Json.encodeToString(items)
+ }
+ }
+
+ {{ generate_structure(name ~ "Item", struct["items"]) }}
+
+{%- elif struct.type == "object" -%}
+ @Serializable
+ data class {{ name }}(
+ {% for itemname, val in struct.properties.items() %}
+ {% if val.type == "object" %}
+ var {{itemname|camelize}}: {{ name ~ "Item" ~ itemname|Camelize ~ "Object" }}? = null,
+ {% elif val.type == "array" %}
+ var {{itemname|camelize}}: {{ name ~ "Item" ~ itemname|Camelize }} = {{ name ~ "Item" ~ itemname|Camelize }}(),
+ {% else %}
+ var {{itemname|camelize}}: {{val.type|structure_type_name}}? = null,
+ {% endif %}
+ {% endfor %}
+ ): ObjectSerialize {
+ override fun intoSerializedObject(): String {
+ return Json.encodeToString(this)
+ }
+ }
+
+ {% for itemname, val in struct.properties.items() %}
+ {% if val.type == "array" %}
+ {% set nested_name = name ~ "Item" ~ itemname|Camelize %}
+ {{ generate_structure(nested_name, val) }}
+ {% elif val.type == "object" %}
+ {% set nested_name = name ~ "Item" ~ itemname|Camelize ~ "Object" %}
+ {{ generate_structure(nested_name, val) }}
+ {% endif %}
+ {% endfor %}
+
+{% endif %}
+
+{% endmacro %}
+
/* ktlint-disable no-blank-line-before-rbrace */
@file:Suppress("PackageNaming", "MaxLineLength")
package {{ namespace }}
@@ -76,8 +131,9 @@ import {{ glean_namespace }}.private.HistogramType // ktlint-disable import-orde
import {{ glean_namespace }}.private.Lifetime // ktlint-disable import-ordering no-unused-imports
import {{ glean_namespace }}.private.MemoryUnit // ktlint-disable import-ordering no-unused-imports
import {{ glean_namespace }}.private.NoExtras // ktlint-disable import-ordering no-unused-imports
-import {{ glean_namespace }}.private.ReasonCode // ktlint-disable import-ordering no-unused-imports
import {{ glean_namespace }}.private.NoReasonCodes // ktlint-disable import-ordering no-unused-imports
+import {{ glean_namespace }}.private.ObjectSerialize // ktlint-disable import-ordering no-unused-imports
+import {{ glean_namespace }}.private.ReasonCode // ktlint-disable import-ordering no-unused-imports
import {{ glean_namespace }}.private.TimeUnit // ktlint-disable import-ordering no-unused-imports
{% for obj_type in obj_types %}
import {{ glean_namespace }}.private.{{ obj_type }} // ktlint-disable import-ordering
@@ -85,6 +141,11 @@ import {{ glean_namespace }}.private.{{ obj_type }} // ktlint-disable import-ord
{% if has_labeled_metrics %}
import {{ glean_namespace }}.private.LabeledMetricType // ktlint-disable import-ordering
{% endif %}
+{% if has_object_metrics %}
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
+{% endif %}
internal object {{ category_name|Camelize }} {
{% for obj in objs.values() %}
@@ -97,6 +158,9 @@ internal object {{ category_name|Camelize }} {
{% endfor %}
{% endif %}
{% else %}
+ {% if obj|attr("_generate_structure") %}
+ {{ generate_structure(obj.name|Camelize ~ "Object", obj._generate_structure) }}
+ {%- endif %}
{% if obj|attr("_generate_enums") %}
{% for name, suffix in obj["_generate_enums"] %}
{% if obj|attr(name)|length %}
diff --git a/third_party/python/glean_parser/glean_parser/templates/rust.jinja2 b/third_party/python/glean_parser/glean_parser/templates/rust.jinja2
index 4c54dd2b2c..269a007ac5 100644
--- a/third_party/python/glean_parser/glean_parser/templates/rust.jinja2
+++ b/third_party/python/glean_parser/glean_parser/templates/rust.jinja2
@@ -87,7 +87,7 @@ impl ExtraKeys for {{ obj.name|Camelize }}{{ suffix }} {
/// {{ obj.description|wordwrap() | replace('\n', '\n/// ') }}
#[rustfmt::skip]
pub static {{ obj.name|snake_case }}: ::glean::private::__export::Lazy<::glean::private::PingType> =
- ::glean::private::__export::Lazy::new(|| ::glean::private::PingType::new("{{ obj.name }}", {{ obj.include_client_id|rust }}, {{ obj.send_if_empty|rust }}, {{ obj.precise_timestamps|rust }}, {{ obj.include_info_sections|rust }}, {{ obj.reason_codes|rust }}));
+ ::glean::private::__export::Lazy::new(|| ::glean::private::PingType::new("{{ obj.name }}", {{ obj.include_client_id|rust }}, {{ obj.send_if_empty|rust }}, {{ obj.precise_timestamps|rust }}, {{ obj.include_info_sections|rust }}, {{ obj.enabled|rust }}, {{ obj.schedules_pings|rust }}, {{ obj.reason_codes|rust }}));
{% endfor %}
{% else %}
pub mod {{ category.name|snake_case }} {
diff --git a/third_party/python/glean_parser/glean_parser/templates/swift.jinja2 b/third_party/python/glean_parser/glean_parser/templates/swift.jinja2
index 714bf20ec2..fe51a078bc 100644
--- a/third_party/python/glean_parser/glean_parser/templates/swift.jinja2
+++ b/third_party/python/glean_parser/glean_parser/templates/swift.jinja2
@@ -11,7 +11,7 @@ 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/. */
-{% macro obj_declaration(obj, suffix='', access='') %}
+{%- macro obj_declaration(obj, suffix='', access='') %}
{{ access }}static let {{ obj.name|camelize|variable_name }}{{ suffix }} = {{ obj|type_name }}( // generated from {{ obj.identifier() }}
CommonMetricData(
{% for arg_name in common_metric_args if obj[arg_name] is defined %}
@@ -24,7 +24,7 @@ Jinja2 template is not. Please file bugs! #}
)
{% endmacro %}
-{% macro struct_decl(obj, name, suffix) %}
+{%- macro struct_decl(obj, name, suffix) %}
struct {{ obj.name|Camelize }}{{ suffix }}: EventExtras {
{% for item, typ in obj|attr(name) %}
var {{ item|camelize|variable_name }}: {{typ|extra_type_name}}?
@@ -44,6 +44,46 @@ struct {{ obj.name|Camelize }}{{ suffix }}: EventExtras {
}
{% endmacro %}
+{%- macro generate_structure(name, struct) %}
+{%- if struct.type == "array" -%}
+ typealias {{ name }} = [{{ name }}Item]
+
+ {{ generate_structure(name ~ "Item", struct["items"]) }}
+
+{%- elif struct.type == "object" -%}
+ struct {{ name }}: Codable, Equatable, ObjectSerialize {
+ {% for itemname, val in struct.properties.items() %}
+ {% if val.type == "object" %}
+ var {{itemname|camelize|variable_name}}: {{ name ~ "Item" ~ itemname|Camelize ~ "Object" }}?
+ {% elif val.type == "array" %}
+ var {{itemname|camelize|variable_name}}: {{ name ~ "Item" ~ itemname|Camelize }}
+ {% else %}
+ var {{itemname|camelize|variable_name}}: {{val.type|structure_type_name}}?
+ {% endif %}
+ {% endfor %}
+
+ func intoSerializedObject() -> String {
+ let jsonEncoder = JSONEncoder()
+ let jsonData = try! jsonEncoder.encode(self)
+ let json = String(data: jsonData, encoding: String.Encoding.utf8)!
+ return json
+ }
+ }
+
+ {% for itemname, val in struct.properties.items() %}
+ {% if val.type == "array" %}
+ {% set nested_name = name ~ "Item" ~ itemname|Camelize %}
+ {{ generate_structure(nested_name, val) }}
+ {% elif val.type == "object" %}
+ {% set nested_name = name ~ "Item" ~ itemname|Camelize ~ "Object" %}
+ {{ generate_structure(nested_name, val) }}
+ {% endif %}
+ {% endfor %}
+
+{%- endif -%}
+
+{% endmacro %}
+
{% if not allow_reserved %}
import {{ glean_namespace }}
@@ -97,6 +137,8 @@ extension {{ namespace }} {
sendIfEmpty: {{obj.send_if_empty|swift}},
preciseTimestamps: {{obj.precise_timestamps|swift}},
includeInfoSections: {{obj.include_info_sections|swift}},
+ enabled: {{obj.enabled|swift}},
+ schedulesPings: {{obj.schedules_pings|swift}},
reasonCodes: {{obj.reason_codes|swift}}
)
@@ -106,6 +148,9 @@ extension {{ namespace }} {
{% else %}
enum {{ category.name|Camelize }} {
{% for obj in category.objs.values() %}
+ {% if obj|attr("_generate_structure") %}
+ {{ generate_structure(obj.name|Camelize ~ "Object", obj._generate_structure) }}
+ {%- endif %}
{% if obj|attr("_generate_enums") %}
{% for name, suffix in obj["_generate_enums"] %}
{% if obj|attr(name)|length %}
diff --git a/third_party/python/glean_parser/glean_parser/util.py b/third_party/python/glean_parser/glean_parser/util.py
index f8bc7d4f53..a61e318dbe 100644
--- a/third_party/python/glean_parser/glean_parser/util.py
+++ b/third_party/python/glean_parser/glean_parser/util.py
@@ -531,6 +531,8 @@ ping_args = [
"send_if_empty",
"precise_timestamps",
"include_info_sections",
+ "enabled",
+ "schedules_pings",
"reason_codes",
]