summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/bindings/scripts/web_idl/database.py
blob: c92cf48eb2ab4f51fcea5f95961f4f69265adbdb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from . import file_io
from .typedef import Typedef
from .union import Union
from .user_defined_type import UserDefinedType


class DatabaseBody(object):
    """
    Database class is a public class to provide read access only, while
    DatabaseBody class is an internal class within web_idl module to support
    both of read and write access in addition to construction of Database
    instances.

    |self._defs| is the storage of IDL definitions in the final shape (not IR),
    in the form of:

        { kind1 : { identifier_a: def_a, identifier_b: def_b, ... },
          kind2 : { ... },
          ...
        }
    """

    class Kind(object):
        CALLBACK_FUNCTION = 'callback function'
        CALLBACK_INTERFACE = 'callback interface'
        DICTIONARY = 'dictionary'
        ENUMERATION = 'enumeration'
        INTERFACE = 'interface'
        INTERFACE_MIXIN = 'interface mixin'
        NAMESPACE = 'namespace'
        TYPEDEF = 'typedef'
        UNION = 'union'

        _ALL_ENTRIES = (
            CALLBACK_FUNCTION,
            CALLBACK_INTERFACE,
            DICTIONARY,
            ENUMERATION,
            INTERFACE,
            INTERFACE_MIXIN,
            NAMESPACE,
            TYPEDEF,
            UNION,
        )

        @classmethod
        def values(cls):
            return cls._ALL_ENTRIES.__iter__()

    def __init__(self):
        self._defs = {}
        for kind in DatabaseBody.Kind.values():
            self._defs[kind] = {}

    def register(self, kind, user_defined_type):
        assert isinstance(user_defined_type, (Typedef, Union, UserDefinedType))
        assert kind in DatabaseBody.Kind.values()
        try:
            self.find_by_identifier(user_defined_type.identifier)
            assert False, user_defined_type.identifier
        except KeyError:
            pass
        self._defs[kind][user_defined_type.identifier] = user_defined_type

    def find_by_identifier(self, identifier):
        for defs_per_kind in self._defs.values():
            if identifier in defs_per_kind:
                return defs_per_kind[identifier]
        raise KeyError(identifier)

    def find_by_kind(self, kind):
        return self._defs[kind]


class Database(object):
    """
    Database class is an entry point for the clients of web_idl module.  All the
    data about IDL definitions will be retrieved from this database.

    Database class provides read access only.
    """

    _Kind = DatabaseBody.Kind

    def __init__(self, database_body):
        assert isinstance(database_body, DatabaseBody)
        self._impl = database_body

    @staticmethod
    def read_from_file(filepath):
        database = file_io.read_pickle_file(filepath)
        assert isinstance(database, Database)
        return database

    def write_to_file(self, filepath):
        return file_io.write_pickle_file_if_changed(filepath, self)

    def find(self, identifier):
        """
        Returns the IDL definition specified with |identifier|.  Raises KeyError
        if not found.
        """
        return self._impl.find_by_identifier(identifier)

    @property
    def callback_functions(self):
        """Returns all callback functions."""
        return self._view_by_kind(Database._Kind.CALLBACK_FUNCTION)

    @property
    def callback_interfaces(self):
        """Returns all callback interfaces."""
        return self._view_by_kind(Database._Kind.CALLBACK_INTERFACE)

    @property
    def dictionaries(self):
        """Returns all dictionaries."""
        return self._view_by_kind(Database._Kind.DICTIONARY)

    @property
    def enumerations(self):
        """Returns all enumerations."""
        return self._view_by_kind(Database._Kind.ENUMERATION)

    @property
    def interfaces(self):
        """
        Returns all interfaces.

        Callback interfaces and mixins are not included.
        """
        return self._view_by_kind(Database._Kind.INTERFACE)

    @property
    def interface_mixins(self):
        """Returns all interface mixins."""
        return self._view_by_kind(Database._Kind.INTERFACE_MIXIN)

    @property
    def namespaces(self):
        """Returns all namespaces."""
        return self._view_by_kind(Database._Kind.NAMESPACE)

    @property
    def typedefs(self):
        """Returns all typedef definitions."""
        return self._view_by_kind(Database._Kind.TYPEDEF)

    @property
    def union_types(self):
        """Returns all union type definitions."""
        return self._view_by_kind(Database._Kind.UNION)

    def _view_by_kind(self, kind):
        return self._impl.find_by_kind(kind).values()