Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/common/devtools/pdl.py
4500 views
1
# Copyright 2018 The Chromium Authors. All rights reserved.
2
# Use of this source code is governed by a BSD-style license that can be
3
# found in the LICENSE file.
4
5
import json
6
import re
7
import sys
8
from collections import OrderedDict
9
from typing import Any
10
11
description = ""
12
13
14
primitiveTypes = [
15
"integer",
16
"number",
17
"boolean",
18
"string",
19
"object",
20
"any",
21
"array",
22
"binary",
23
]
24
25
26
def assignType(item: dict, type: str, is_array: bool = False, map_binary_to_string: bool = False) -> None:
27
if is_array:
28
item["type"] = "array"
29
item["items"] = OrderedDict()
30
assignType(item["items"], type, False, map_binary_to_string)
31
return
32
33
if type == "enum":
34
type = "string"
35
if map_binary_to_string and type == "binary":
36
type = "string"
37
if type in primitiveTypes:
38
item["type"] = type
39
else:
40
item["$ref"] = type
41
42
43
def createItem(
44
d: dict, experimental: bool | Any, deprecated: bool | Any, name: str | Any = None
45
) -> OrderedDict[str, Any]:
46
result = OrderedDict(d)
47
if name:
48
result["name"] = name
49
global description
50
if description:
51
result["description"] = description.strip()
52
if experimental:
53
result["experimental"] = True
54
if deprecated:
55
result["deprecated"] = True
56
return result
57
58
59
def parse(data: str, file_name: str, map_binary_to_string: bool = False) -> OrderedDict[str, Any]:
60
protocol = OrderedDict()
61
protocol["version"] = OrderedDict()
62
protocol["domains"] = []
63
domain = None
64
item = None
65
subitems = None
66
nukeDescription = False
67
global description
68
lines = data.split("\n")
69
for i in range(0, len(lines)):
70
if nukeDescription:
71
description = ""
72
nukeDescription = False
73
line = lines[i]
74
trimLine = line.strip()
75
76
if trimLine.startswith("#"):
77
if len(description):
78
description += "\n"
79
description += trimLine[2:]
80
continue
81
else:
82
nukeDescription = True
83
84
if len(trimLine) == 0:
85
continue
86
87
match = re.compile(r"^(experimental )?(deprecated )?domain (.*)").match(line)
88
if match:
89
domain = createItem({"domain": match.group(3)}, match.group(1), match.group(2))
90
protocol["domains"].append(domain)
91
continue
92
93
match = re.compile(r"^ depends on ([^\s]+)").match(line)
94
if match:
95
if "dependencies" not in domain:
96
domain["dependencies"] = []
97
domain["dependencies"].append(match.group(1))
98
continue
99
100
match = re.compile(
101
r"^ (experimental )?(deprecated )?type (.*) "
102
r"extends (array of )?([^\s]+)"
103
).match(line)
104
if match:
105
if "types" not in domain:
106
domain["types"] = []
107
item = createItem({"id": match.group(3)}, match.group(1), match.group(2))
108
assignType(item, match.group(5), match.group(4), map_binary_to_string)
109
domain["types"].append(item)
110
continue
111
112
match = re.compile(r"^ (experimental )?(deprecated )?(command|event) (.*)").match(line)
113
if match:
114
list = []
115
if match.group(3) == "command":
116
if "commands" in domain:
117
list = domain["commands"]
118
else:
119
list = domain["commands"] = []
120
else:
121
if "events" in domain:
122
list = domain["events"]
123
else:
124
list = domain["events"] = []
125
126
item = createItem({}, match.group(1), match.group(2), match.group(4))
127
list.append(item)
128
continue
129
130
match = re.compile(
131
r"^ (experimental )?(deprecated )?(optional )?"
132
r"(array of )?([^\s]+) ([^\s]+)"
133
).match(line)
134
if match:
135
param = createItem({}, match.group(1), match.group(2), match.group(6))
136
if match.group(3):
137
param["optional"] = True
138
assignType(param, match.group(5), match.group(4), map_binary_to_string)
139
if match.group(5) == "enum":
140
enumliterals = param["enum"] = []
141
subitems.append(param)
142
continue
143
144
match = re.compile(r"^ (parameters|returns|properties)").match(line)
145
if match:
146
subitems = item[match.group(1)] = []
147
continue
148
149
match = re.compile(r"^ enum").match(line)
150
if match:
151
enumliterals = item["enum"] = []
152
continue
153
154
match = re.compile(r"^version").match(line)
155
if match:
156
continue
157
158
match = re.compile(r"^ major (\d+)").match(line)
159
if match:
160
protocol["version"]["major"] = match.group(1)
161
continue
162
163
match = re.compile(r"^ minor (\d+)").match(line)
164
if match:
165
protocol["version"]["minor"] = match.group(1)
166
continue
167
168
match = re.compile(r"^ redirect ([^\s]+)").match(line)
169
if match:
170
item["redirect"] = match.group(1)
171
continue
172
173
match = re.compile(r"^ ( )?[^\s]+$").match(line)
174
if match:
175
# enum literal
176
enumliterals.append(trimLine)
177
continue
178
179
print(f"Error in {file_name}:{i}, illegal token: \t{line}")
180
sys.exit(1)
181
return protocol
182
183
184
def loads(data: str, file_name: str, map_binary_to_string: bool = False) -> OrderedDict[str, Any] | Any:
185
if file_name.endswith(".pdl"):
186
return parse(data, file_name, map_binary_to_string)
187
return json.loads(data)
188
189