Bug 1896638 - Export some IPDL information as JSON. r=nika

Differential Revision: https://phabricator.services.mozilla.com/D210326
This commit is contained in:
Christian Holler (:decoder) 2024-06-07 10:22:48 +00:00
parent 535e996010
commit e0ae53527b
2 changed files with 81 additions and 0 deletions

View file

@ -1,6 +1,7 @@
# 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 json
import optparse
import os
import sys
@ -10,6 +11,7 @@ from multiprocessing import Manager
import ipdl
from ipdl.ast import SYNC
from ipdl.exporter import JSONExporter
class WorkerPool:
@ -27,6 +29,7 @@ class WorkerPool:
allprotocols,
allmessageprognames,
allsyncmessages,
alljsonobjs,
*,
processes=None
):
@ -47,6 +50,7 @@ class WorkerPool:
allprotocols,
allmessageprognames,
allsyncmessages,
alljsonobjs,
),
processes=processes,
)
@ -70,6 +74,7 @@ class WorkerPool:
allprotocols,
allmessageprognames,
allsyncmessages,
alljsonobjs,
) = WorkerPool.per_process_context
ast = asts[index]
ipdl.gencxx(files[index], ast, headersdir, cppdir, segmentCapacityDict)
@ -78,6 +83,8 @@ class WorkerPool:
allmessages[ast.protocol.name] = ipdl.genmsgenum(ast)
allprotocols.append(ast.protocol.name)
alljsonobjs.append(JSONExporter.protocolToObject(ast.protocol))
# e.g. PContent::RequestMemoryReport (not prefixed or suffixed.)
for md in ast.protocol.messageDecls:
allmessageprognames.append("%s::%s" % (md.namespace, md.decl.progname))
@ -216,6 +223,7 @@ def main():
allsyncmessages = manager.list()
allmessageprognames = manager.list()
allprotocols = manager.list()
alljsonobjs = manager.list()
for msgName in msgMetadataConfig.sections():
if msgMetadataConfig.has_option(msgName, "segment_capacity"):
@ -271,9 +279,19 @@ def main():
allprotocols,
allmessageprognames,
allsyncmessages,
alljsonobjs,
)
pool.run()
if cppdir is not None:
# Sort to ensure deterministic output
alljsonobjs = list(alljsonobjs)
alljsonobjs.sort(key=lambda p: p["name"])
ipdl.writeifmodified(
json.dumps({"protocols": alljsonobjs}, indent=2),
os.path.join(cppdir, "protocols.json"),
)
allprotocols.sort()
allsyncmessages.sort()

63
ipc/ipdl/ipdl/exporter.py Normal file
View file

@ -0,0 +1,63 @@
# vim: set ts=4 sw=4 tw=99 et:
# 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 json
import os
import sys
from ipdl.ast import ASYNC, SYNC
from ipdl.ast import IN, OUT, INOUT
from ipdl.ast import StringLiteral
from pprint import pprint
# We export some protocol data to JSON so it can be consumed and processed
# further by external tooling, such as Fuzzing/Security to automatically
# determine security boundaries and generate code coverage filters for
# certain protocols.
class JSONExporter:
@staticmethod
def protocolToObject(protocol):
def implToString(impl):
if impl is None:
return None
if type(impl) is StringLiteral:
return str(impl.value)
return str(impl)
p = {
"name": protocol.name,
"namespaces": [x.name for x in protocol.namespaces],
"managers": [x.name for x in protocol.managers],
"parent_methods": [],
"child_methods": [],
"attributes": {
x.name: implToString(x.value) for x in protocol.attributes.values()
},
}
for md in protocol.messageDecls:
def serialize_md(md):
return {
"name": md.decl.progname,
"attributes": {x.name: x.value for x in md.attributes.values()},
"sync": md.sendSemantics == SYNC,
"params": [
{"type": x.ipdltype.name(), "name": x.name} for x in md.params
],
}
if md.direction == IN or md.direction == INOUT:
p["parent_methods"].append(serialize_md(md))
if md.direction == OUT or md.direction == INOUT:
p["child_methods"].append(serialize_md(md))
return p