Backed out changeset ac12dbbe7b63 (bug 1302663) for leaks and eslint failure. r=backout
authorSebastian Hengst <archaeopteryx@coole-files.de>
Sat, 12 Nov 2016 21:18:23 +0100
changeset 349043 557a7e72a15086747793eb5dd0642c4f149b0937
parent 349042 215e84d751786dcf690f1a7511aa9806b2dc9a0b
child 349044 bc90683c3cebe4f6ad52da469a4694a3e7cbf02c
push id10298
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:33:03 +0000
treeherdermozilla-aurora@7e29173b1641 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1302663
milestone52.0a1
backs outac12dbbe7b632995c7b7f46e0394979de8d28e72
Backed out changeset ac12dbbe7b63 (bug 1302663) for leaks and eslint failure. r=backout
toolkit/components/telemetry/EventInfo.h
toolkit/components/telemetry/Events.yaml
toolkit/components/telemetry/gen-event-data.py
toolkit/components/telemetry/gen-event-enum.py
toolkit/components/telemetry/moz.build
toolkit/components/telemetry/parse_events.py
deleted file mode 100644
--- a/toolkit/components/telemetry/EventInfo.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
-/* 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 TelemetryEventInfo_h__
-#define TelemetryEventInfo_h__
-
-// This module is internal to Telemetry. The structures here hold data that
-// describe events.
-// It should only be used by TelemetryEventData.h and TelemetryEvent.cpp.
-//
-// For the public interface to Telemetry functionality, see Telemetry.h.
-
-namespace {
-
-struct CommonEventInfo {
-  // Indices for the category and expiration strings.
-  uint32_t category_offset;
-  uint32_t expiration_version_offset;
-
-  // The index and count for the extra key offsets in the extra table.
-  uint32_t extra_index;
-  uint32_t extra_count;
-
-  // The day since UNIX epoch that this probe expires on.
-  uint32_t expiration_day;
-
-  // The dataset this event is recorded in.
-  uint32_t dataset;
-
-  // Convenience functions for accessing event strings.
-  const char* expiration_version() const;
-  const char* category() const;
-  const char* extra_key(uint32_t index) const;
-};
-
-struct EventInfo {
-  // The corresponding CommonEventInfo.
-  const CommonEventInfo& common_info;
-
-  // Indices for the method & object strings.
-  uint32_t method_offset;
-  uint32_t object_offset;
-
-  const char* method() const;
-  const char* object() const;
-};
-
-} // namespace
-
-#endif // TelemetryEventInfo_h__
deleted file mode 100644
--- a/toolkit/components/telemetry/Events.yaml
+++ /dev/null
@@ -1,53 +0,0 @@
-# This category contains event entries used for Telemetry tests.
-# They will not be sent out with any pings.
-telemetry.test:
-- methods: ["test1", "test2"]
-  objects: ["object1", "object2"]
-  bug_numbers: [1286606]
-  notification_emails: ["telemetry-client-dev@mozilla.com"]
-  description: This is a test entry for Telemetry.
-  expiry_date: never
-  extra_keys:
-    key1: This is just a test description.
-    key2: This is another test description.
-- methods: ["test_optout"]
-  objects: ["object1", "object2"]
-  bug_numbers: [1286606]
-  notification_emails: ["telemetry-client-dev@mozilla.com"]
-  description: This is an opt-out test entry.
-  expiry_date: never
-  release_channel_collection: opt-out
-  extra_keys:
-    key1: This is just a test description.
-- methods: ["test_expired_version"]
-  objects: ["object1", "object2"]
-  bug_numbers: [1286606]
-  notification_emails: ["telemetry-client-dev@mozilla.com"]
-  description: This is a test entry with an expired version.
-  expiry_version: "3.6"
-- methods: ["test_expired_date"]
-  objects: ["object1", "object2"]
-  bug_numbers: [1286606]
-  notification_emails: ["telemetry-client-dev@mozilla.com"]
-  description: This is a test entry with an expired date.
-  expiry_date: 2014-01-28
-- methods: ["test_not_expired_optout"]
-  objects: ["object1"]
-  bug_numbers: [1286606]
-  notification_emails: ["telemetry-client-dev@mozilla.com"]
-  description: This is an opt-out test entry with unexpired date and version.
-  release_channel_collection: opt-out
-  expiry_date: 2099-01-01
-  expiry_version: "999.0"
-
-# This is a secondary category used for Telemetry tests.
-# The events here will not be sent out with any pings.
-telemetry.test.second:
-- methods: ["test"]
-  objects: ["object1", "object2", "object3"]
-  bug_numbers: [1286606]
-  notification_emails: ["telemetry-client-dev@mozilla.com"]
-  description: This is a test entry for Telemetry.
-  expiry_date: never
-  extra_keys:
-    key1: This is just a test description.
deleted file mode 100644
--- a/toolkit/components/telemetry/gen-event-data.py
+++ /dev/null
@@ -1,142 +0,0 @@
-# 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/.
-
-# Write out event information for C++. The events are defined
-# in a file provided as a command-line argument.
-
-from __future__ import print_function
-from shared_telemetry_utils import StringTable, static_assert
-
-import parse_events
-import sys
-import itertools
-
-# The banner/text at the top of the generated file.
-banner = """/* This file is auto-generated, only for internal use in TelemetryEvent.h,
-   see gen-event-data.py. */
-"""
-
-file_header = """\
-#ifndef mozilla_TelemetryEventData_h
-#define mozilla_TelemetryEventData_h
-#include "EventInfo.h"
-namespace {
-"""
-
-file_footer = """\
-} // namespace
-#endif // mozilla_TelemetryEventData_h
-"""
-
-def write_extra_table(events, output, string_table):
-    table_name = "gExtraKeysTable"
-    extra_table = []
-    extra_count = 0
-
-    print("const uint32_t %s[] = {" % table_name, file=output)
-
-    for e in events:
-        extra_index = 0
-        extra_keys = e.extra_keys
-        if len(extra_keys) > 0:
-            extra_index = extra_count
-            extra_count += len(extra_keys)
-            indexes = string_table.stringIndexes(extra_keys)
-
-            print("  // %s, [%s], [%s]" % (
-                    e.category,
-                    ", ".join(e.methods),
-                    ", ".join(e.objects)),
-                  file=output)
-            print("  // extra_keys: %s" % ", ".join(extra_keys), file=output)
-            print("  %s," % ", ".join(map(str, indexes)),
-                  file=output)
-
-        extra_table.append((extra_index, len(extra_keys)))
-
-    print("};", file=output)
-    static_assert(output, "sizeof(%s) <= UINT32_MAX" % table_name,
-                  "index overflow")
-
-    return extra_table
-
-def write_common_event_table(events, output, string_table, extra_table):
-    table_name = "gCommonEventInfo"
-    extra_count = 0
-
-    print("const CommonEventInfo %s[] = {" % table_name, file=output)
-    for e,extras in zip(events, extra_table):
-        # Write a comment to make the file human-readable.
-        print("  // category: %s" % e.category, file=output)
-        print("  // methods: [%s]" % ", ".join(e.methods), file=output)
-        print("  // objects: [%s]" % ", ".join(e.objects), file=output)
-
-        # Write the common info structure
-        print("  {%d, %d, %d, %d, %d, %s}," %
-                (string_table.stringIndex(e.category),
-                 string_table.stringIndex(e.expiry_version),
-                 extras[0], # extra keys index
-                 extras[1], # extra keys count
-                 e.expiry_day,
-                 e.dataset),
-              file=output)
-
-    print("};", file=output)
-    static_assert(output, "sizeof(%s) <= UINT32_MAX" % table_name,
-                  "index overflow")
-
-def write_event_table(events, output, string_table):
-    table_name = "gEventInfo"
-    print("const EventInfo %s[] = {" % table_name, file=output)
-
-    for common_info_index,e in enumerate(events):
-        for method_name, object_name in itertools.product(e.methods, e.objects):
-            print("  // category: %s, method: %s, object: %s" %
-                    (e.category, method_name, object_name),
-                  file=output)
-
-            print("  {gCommonEventInfo[%d], %d, %d}," %
-                    (common_info_index,
-                     string_table.stringIndex(method_name),
-                     string_table.stringIndex(object_name)),
-                  file=output)
-
-    print("};", file=output)
-    static_assert(output, "sizeof(%s) <= UINT32_MAX" % table_name,
-                  "index overflow")
-
-def main(output, *filenames):
-    # Load the event data.
-    if len(filenames) > 1:
-        raise Exception('We don\'t support loading from more than one file.')
-    events = parse_events.load_events(filenames[0])
-
-    # Write the scalar data file.
-    print(banner, file=output)
-    print(file_header, file=output)
-
-    # Write the extra keys table.
-    string_table = StringTable()
-    extra_table = write_extra_table(events, output, string_table)
-    print("", file=output)
-
-    # Write a table with the common event data.
-    write_common_event_table(events, output, string_table, extra_table)
-    print("", file=output)
-
-    # Write the data for individual events.
-    write_event_table(events, output, string_table)
-    print("", file=output)
-
-    # Write the string table.
-    string_table_name = "gEventsStringTable"
-    string_table.writeDefinition(output, string_table_name)
-    static_assert(output, "sizeof(%s) <= UINT32_MAX" % string_table_name,
-                  "index overflow")
-    print("", file=output)
-
-    print(file_footer, file=output)
-
-if __name__ == '__main__':
-    main(sys.stdout, *sys.argv[1:])
deleted file mode 100644
--- a/toolkit/components/telemetry/gen-event-enum.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# 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/.
-
-# Write out C++ enum definitions that represent the different event types.
-#
-# The events are defined in files provided as command-line arguments.
-
-from __future__ import print_function
-
-import sys
-import parse_events
-
-banner = """/* This file is auto-generated, see gen-event-enum.py.  */
-"""
-
-file_header = """\
-#ifndef mozilla_TelemetryEventEnums_h
-#define mozilla_TelemetryEventEnums_h
-namespace mozilla {
-namespace Telemetry {
-namespace EventID {
-"""
-
-file_footer = """\
-} // namespace EventID
-} // namespace mozilla
-} // namespace Telemetry
-#endif // mozilla_TelemetryEventEnums_h
-"""
-
-def main(output, *filenames):
-    # Load the events first.
-    if len(filenames) > 1:
-        raise Exception('We don\'t support loading from more than one file.')
-    events = parse_events.load_events(filenames[0])
-
-    grouped = dict()
-    index = 0
-    for e in events:
-        category = e.category
-        if not category in grouped:
-            grouped[category] = []
-        grouped[category].append((index, e))
-        index += len(e.enum_labels)
-
-    # Write the enum file.
-    print(banner, file=output)
-    print(file_header, file=output);
-
-    for category,indexed in grouped.iteritems():
-        category_cpp = indexed[0][1].category_cpp
-
-        print("// category: %s" % category, file=output)
-        print("enum class %s : uint32_t {" % category_cpp, file=output)
-
-        for event_index,e in indexed:
-            cpp_guard = e.cpp_guard
-            if cpp_guard:
-                print("#if defined(%s)" % cpp_guard, file=output)
-            for offset,label in enumerate(e.enum_labels):
-                print("  %s = %d," % (label, event_index + offset), file=output)
-            if cpp_guard:
-                print("#endif", file=output)
-
-        print("};\n", file=output)
-
-    print("const uint32_t EventCount = %d;\n" % index, file=output)
-
-    print(file_footer, file=output)
-
-if __name__ == '__main__':
-    main(sys.stdout, *sys.argv[1:])
--- a/toolkit/components/telemetry/moz.build
+++ b/toolkit/components/telemetry/moz.build
@@ -1,32 +1,16 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 HAS_MISC_RULE = True
 
-include('/ipc/chromium/chromium-config.mozbuild')
-
-FINAL_LIBRARY = 'xul'
-
-DEFINES['MOZ_APP_VERSION'] = '"%s"' % CONFIG['MOZ_APP_VERSION']
-
-LOCAL_INCLUDES += [
-    '/xpcom/build',
-    '/xpcom/threads',
-]
-
-SPHINX_TREES['telemetry'] = 'docs'
-
-if CONFIG['GNU_CXX']:
-    CXXFLAGS += ['-Wno-error=shadow']
-
 XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
 BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
 
 XPIDL_SOURCES += [
     'nsITelemetry.idl',
 ]
 
 XPIDL_MODULE = 'telemetry'
@@ -69,60 +53,60 @@ EXTRA_JS_MODULES += [
     'ThirdPartyCookieProbe.jsm',
     'UITelemetry.jsm',
 ]
 
 TESTING_JS_MODULES += [
   'tests/unit/TelemetryArchiveTesting.jsm',
 ]
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
+FINAL_LIBRARY = 'xul'
+
 GENERATED_FILES = [
-    'TelemetryEventData.h',
-    'TelemetryEventEnums.h',
     'TelemetryHistogramData.inc',
     'TelemetryHistogramEnums.h',
     'TelemetryScalarData.h',
     'TelemetryScalarEnums.h',
 ]
 
-# Generate histogram files.
 histogram_files = [
     'Histograms.json',
     '/dom/base/UseCounters.conf',
     '/dom/base/nsDeprecatedOperationList.h',
 ]
 
 data = GENERATED_FILES['TelemetryHistogramData.inc']
 data.script = 'gen-histogram-data.py'
 data.inputs = histogram_files
 
 enums = GENERATED_FILES['TelemetryHistogramEnums.h']
 enums.script = 'gen-histogram-enum.py'
 enums.inputs = histogram_files
 
-# Generate scalar files.
+# Generate Scalars
 scalar_files = [
     'Scalars.yaml',
 ]
 
 scalar_data = GENERATED_FILES['TelemetryScalarData.h']
 scalar_data.script = 'gen-scalar-data.py'
 scalar_data.inputs = scalar_files
 
 scalar_enums = GENERATED_FILES['TelemetryScalarEnums.h']
 scalar_enums.script = 'gen-scalar-enum.py'
 scalar_enums.inputs = scalar_files
 
-# Generate event files.
-event_files = [
-    'Events.yaml',
+DEFINES['MOZ_APP_VERSION'] = '"%s"' % CONFIG['MOZ_APP_VERSION']
+
+LOCAL_INCLUDES += [
+    '/xpcom/build',
+    '/xpcom/threads',
 ]
 
-event_data = GENERATED_FILES['TelemetryEventData.h']
-event_data.script = 'gen-event-data.py'
-event_data.inputs = event_files
+SPHINX_TREES['telemetry'] = 'docs'
 
-event_enums = GENERATED_FILES['TelemetryEventEnums.h']
-event_enums.script = 'gen-event-enum.py'
-event_enums.inputs = event_files
+if CONFIG['GNU_CXX']:
+    CXXFLAGS += ['-Wno-error=shadow']
 
 with Files('**'):
     BUG_COMPONENT = ('Toolkit', 'Telemetry')
deleted file mode 100644
--- a/toolkit/components/telemetry/parse_events.py
+++ /dev/null
@@ -1,271 +0,0 @@
-# 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/.
-
-import re
-import yaml
-import itertools
-import datetime
-import string
-from shared_telemetry_utils import add_expiration_postfix
-
-MAX_CATEGORY_NAME_LENGTH = 100
-MAX_METHOD_NAME_LENGTH = 40
-MAX_OBJECT_NAME_LENGTH = 40
-MAX_EXTRA_KEYS_COUNT = 20
-MAX_EXTRA_KEY_NAME_LENGTH = 20
-
-IDENTIFIER_PATTERN = r'^[a-zA-Z][a-zA-Z0-9_.]+[a-zA-Z0-9]$'
-DATE_PATTERN = r'^[0-9]{4}-[0-9]{2}-[0-9]{2}$'
-
-def nice_type_name(t):
-    if isinstance(t, basestring):
-        return "string"
-    return t.__name__
-
-def convert_to_cpp_identifier(s, sep):
-    return string.capwords(s, sep).replace(sep, "")
-
-class OneOf:
-    """This is a placeholder type for the TypeChecker below.
-    It signals that the checked value should match one of the following arguments
-    passed to the TypeChecker constructor.
-    """
-    pass
-
-class TypeChecker:
-    """This implements a convenience type TypeChecker to make the validation code more readable."""
-    def __init__(self, kind, *args):
-        """This takes 1-3 arguments, specifying the value type to check for.
-        It supports:
-        - atomic values, e.g.: TypeChecker(int)
-        - list values, e.g.: TypeChecker(list, basestring)
-        - dict values, e.g.: TypeChecker(dict, basestring, int)
-        - atomic values that can have different types, e.g.: TypeChecker(OneOf, int, date)"""
-        self._kind = kind
-        self._args = args
-
-    def check(self, key, value):
-        # Check fields that can be one of two different types.
-        if self._kind is OneOf:
-            if not isinstance(value, self._args[0]) and not isinstance(value, self._args[1]):
-                raise ValueError, "failed type check for %s - expected %s or %s, got %s" %\
-                                  (key,
-                                   nice_type_name(self._args[0]),
-                                   nice_type_name(self._args[1]),
-                                   nice_type_name(type(value)))
-            return
-
-        # Check basic type of value.
-        if not isinstance(value, self._kind):
-            raise ValueError, "failed type check for %s - expected %s, got %s" %\
-                              (key,
-                               nice_type_name(self._kind),
-                               nice_type_name(type(value)))
-
-        # Check types of values in lists.
-        if self._kind is list:
-            if len(value) < 1:
-                raise ValueError, "failed check for %s - list should not be empty" % key
-            for x in value:
-                if not isinstance(x, self._args[0]):
-                    raise ValueError, "failed type check for %s - expected list value type %s, got %s" %\
-                                      (key,
-                                       nice_type_name(self._args[0]),
-                                       nice_type_name(type(x)))
-        # Check types of keys and values in dictionaries.
-        elif self._kind is dict:
-            if len(value.keys()) < 1:
-                    raise ValueError, "failed check for %s - dict should not be empty" % key
-            for x in value.iterkeys():
-                if not isinstance(x, self._args[0]):
-                    raise ValueError, "failed dict type check for %s - expected key type %s, got %s" %\
-                                      (key,
-                                       nice_type_name(self._args[0]),
-                                       nice_type_name(type(x)))
-            for k,v in value.iteritems():
-                if not isinstance(x, self._args[1]):
-                    raise ValueError, "failed dict type check for %s - expected value type %s for key %s, got %s" %\
-                                      (key,
-                                       nice_type_name(self._args[1]),
-                                       k,
-                                       nice_type_name(type(x)))
-
-def type_check_event_fields(category, definition):
-    """Perform a type/schema check on the event definition."""
-    REQUIRED_FIELDS = {
-        'methods': TypeChecker(list, basestring),
-        'objects': TypeChecker(list, basestring),
-        'bug_numbers': TypeChecker(list, int),
-        'notification_emails': TypeChecker(list, basestring),
-        'description': TypeChecker(basestring),
-    }
-    OPTIONAL_FIELDS = {
-        'release_channel_collection': TypeChecker(basestring),
-        'expiry_date': TypeChecker(OneOf, basestring, datetime.date),
-        'expiry_version': TypeChecker(basestring),
-        'extra_keys': TypeChecker(dict, basestring, basestring),
-    }
-    ALL_FIELDS = REQUIRED_FIELDS.copy()
-    ALL_FIELDS.update(OPTIONAL_FIELDS)
-
-    # Check that all the required fields are available.
-    missing_fields = [f for f in REQUIRED_FIELDS.keys() if f not in definition]
-    if len(missing_fields) > 0:
-        raise KeyError(category + ' - missing required fields: ' + ', '.join(missing_fields))
-
-    # Is there any unknown field?
-    unknown_fields = [f for f in definition.keys() if f not in ALL_FIELDS]
-    if len(unknown_fields) > 0:
-        raise KeyError(category + ' - unknown fields: ' + ', '.join(unknown_fields))
-
-    # Type-check fields.
-    for k,v in definition.iteritems():
-        ALL_FIELDS[k].check(k, v)
-
-def string_check(category, field_name, value, min_length, max_length, regex=None):
-    # Length check.
-    if len(value) > max_length:
-        raise ValueError("Value for %s in %s exceeds maximum length of %d" %\
-                         (field_name, category, max_length))
-    # Regex check.
-    if regex and not re.match(regex, value):
-        raise ValueError, 'String value for %s in %s is not matching pattern "%s": %s' % \
-                          (field_name, category, regex, value)
-
-class EventData:
-    """A class representing one event."""
-
-    def __init__(self, category, definition):
-        type_check_event_fields(category, definition)
-
-        string_check(category, 'methods', definition.get('methods')[0], 1, MAX_METHOD_NAME_LENGTH, regex=IDENTIFIER_PATTERN)
-        string_check(category, 'objects', definition.get('objects')[0], 1, MAX_OBJECT_NAME_LENGTH, regex=IDENTIFIER_PATTERN)
-
-        # Check release_channel_collection
-        rcc_key = 'release_channel_collection'
-        rcc = definition.get(rcc_key, 'opt-in')
-        allowed_rcc = ["opt-in", "opt-out"]
-        if not rcc in allowed_rcc:
-            raise ValueError, "Value for %s in %s should be one of: %s" %\
-                              (rcc_key, category, ", ".join(allowed_rcc))
-
-        # Check extra_keys.
-        extra_keys = definition.get('extra_keys', {})
-        if len(extra_keys.keys()) > MAX_EXTRA_KEYS_COUNT:
-            raise ValueError, "Number of extra_keys in %s exceeds limit %d" %\
-                              (category, MAX_EXTRA_KEYS_COUNT)
-        for key in extra_keys.iterkeys():
-            string_check(category, 'extra_keys', key, 1, MAX_EXTRA_KEY_NAME_LENGTH, regex=IDENTIFIER_PATTERN)
-
-        # Check expiry.
-        if not 'expiry_version' in definition and not 'expiry_date' in definition:
-            raise KeyError, "Event in %s is missing an expiration - either expiry_version or expiry_date is required" %\
-                            (category)
-        expiry_date = definition.get('expiry_date')
-        if expiry_date and isinstance(expiry_date, basestring) and expiry_date != 'never':
-            if not re.match(DATE_PATTERN, expiry_date):
-                raise ValueError, "Event in %s has invalid expiry_date, it should be either 'never' or match this format: %s" %\
-                                  (category, DATE_PATTERN)
-            # Parse into date.
-            definition['expiry_date'] = datetime.datetime.strptime(expiry_date, '%Y-%m-%d')
-
-        # Finish setup.
-        self._category = category
-        self._definition = definition
-        definition['expiry_version'] = add_expiration_postfix(definition.get('expiry_version', 'never'))
-
-    @property
-    def category(self):
-        return self._category
-
-    @property
-    def category_cpp(self):
-        # Transform e.g. category.example into CategoryExample.
-        return convert_to_cpp_identifier(self._category, ".")
-
-    @property
-    def methods(self):
-        return self._definition.get('methods')
-
-    @property
-    def objects(self):
-        return self._definition.get('objects')
-
-    @property
-    def expiry_version(self):
-        return self._definition.get('expiry_version')
-
-    @property
-    def expiry_day(self):
-        date = self._definition.get('expiry_date')
-        if not date:
-            return 0
-        if isinstance(date, basestring) and date == 'never':
-            return 0
-
-        # Convert date to days since UNIX epoch.
-        epoch = datetime.date(1970, 1, 1)
-        days = (date - epoch).total_seconds() / (24 * 60 * 60)
-        return round(days)
-
-    @property
-    def cpp_guard(self):
-        return self._definition.get('cpp_guard')
-
-    @property
-    def enum_labels(self):
-        def enum(method_name, object_name):
-            m = convert_to_cpp_identifier(method_name, "_")
-            o = convert_to_cpp_identifier(object_name, "_")
-            return m + '_' + o
-        combinations = itertools.product(self.methods, self.objects)
-        return [enum(t[0], t[1]) for t in combinations]
-
-    @property
-    def dataset(self):
-        """Get the nsITelemetry constant equivalent for release_channel_collection.
-        """
-        rcc = self._definition.get('release_channel_collection', 'opt-in')
-        if rcc == 'opt-out':
-            return 'nsITelemetry::DATASET_RELEASE_CHANNEL_OPTOUT'
-        else:
-            return 'nsITelemetry::DATASET_RELEASE_CHANNEL_OPTIN'
-
-    @property
-    def extra_keys(self):
-        return self._definition.get('extra_keys', {}).keys()
-
-def load_events(filename):
-    """Parses a YAML file containing the event definitions.
-
-    :param filename: the YAML file containing the event definitions.
-    :raises Exception: if the event file cannot be opened or parsed.
-    """
-
-    # Parse the event definitions from the YAML file.
-    events = None
-    try:
-        with open(filename, 'r') as f:
-            events = yaml.safe_load(f)
-    except IOError, e:
-        raise Exception('Error opening ' + filename + ': ' + e.message)
-    except ValueError, e:
-        raise Exception('Error parsing events in ' + filename + ': ' + e.message)
-
-    event_list = []
-
-    # Events are defined in a fixed two-level hierarchy within the definition file.
-    # The first level contains the category (group name), while the second level contains the
-    # event definitions (e.g. "category.name: [<event definition>, ...], ...").
-    for category_name,category in events.iteritems():
-        string_check('', 'category', category_name, 1, MAX_CATEGORY_NAME_LENGTH, regex=IDENTIFIER_PATTERN)
-
-        # Make sure that the category has at least one entry in it.
-        if not category or len(category) == 0:
-            raise ValueError(category_name + ' must contain at least one entry')
-
-        for entry in category:
-            event_list.append(EventData(category_name, entry))
-
-    return event_list