Commit 767905bf authored by Asanka Herath's avatar Asanka Herath Committed by Commit Bot

Build a more comprehensive database of APIs shipped in Chromium.

Previously the Privacy Budget project added a tool to generate a list of
APIs along with enough information to keep track of which ones have been
marked with `HighEntropy`. This CL replaces that tool with one which
captures a bit more detail about APIs.

Bug: 1144960
Change-Id: I281b713839bf22e38d1963a54290f891dcd624ca
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2515283Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarYuki Shiino <yukishiino@chromium.org>
Reviewed-by: default avatarAlex Turner <alexmt@chromium.org>
Commit-Queue: Asanka Herath <asanka@chromium.org>
Cr-Commit-Position: refs/heads/master@{#825412}
parent d8f82289
......@@ -1354,8 +1354,6 @@ _GENERIC_PYDEPS_FILES = [
'third_party/blink/renderer/bindings/scripts/build_web_idl_database.pydeps',
'third_party/blink/renderer/bindings/scripts/collect_idl_files.pydeps',
'third_party/blink/renderer/bindings/scripts/generate_bindings.pydeps',
('third_party/blink/renderer/bindings/scripts/'
'generate_high_entropy_list.pydeps'),
'tools/binary_size/sizes.pydeps',
'tools/binary_size/supersize.pydeps',
]
......
......@@ -49,3 +49,12 @@ source_set("test_support") {
"//third_party/blink/public/common:common_export",
]
}
# Adds //tools/privacy_budget targets to the top level "gn_all" group. See the
# top level //BUILD.gn file for details on how that target is used. Builders
# that build the "all" target also build the targets in //tools/privacy_budget
# as a result of this dependency.
group("gn_all") {
testonly = true
deps = [ "//tools/privacy_budget:privacy_budget_tools" ]
}
......@@ -139,6 +139,8 @@ collect_idl_files("web_idl_in_modules_for_testing") {
}
action_with_pydeps("web_idl_database") {
visibility += [ "//tools/privacy_budget/blink_apis:*" ]
# TODO(crbug.com/1112471): Get this to run cleanly under Python 3.
run_under_python2 = true
......@@ -150,12 +152,11 @@ action_with_pydeps("web_idl_database") {
get_target_outputs(":web_idl_in_modules_for_testing")
runtime_enabled_features_file = "../platform/runtime_enabled_features.json5"
inputs = input_data_files + [ runtime_enabled_features_file ]
output_data_file = "${bindings_output_dir}/web_idl_database.pickle"
outputs = [ output_data_file ]
outputs = [ web_idl_database_filepath ]
args = [
"--output",
rebase_path(output_data_file, root_build_dir),
rebase_path(web_idl_database_filepath, root_build_dir),
"--runtime_enabled_features",
rebase_path(runtime_enabled_features_file, root_build_dir),
"--",
......@@ -237,29 +238,6 @@ generate_bindings("generate_bindings_all") {
}
}
action_with_pydeps("generate_high_entropy_list") {
# TODO(crbug.com/1112471): Get this to run cleanly under Python 3.
run_under_python2 = true
script = "${bindings_scripts_dir}/generate_high_entropy_list.py"
web_idl_database_outputs = get_target_outputs(":web_idl_database")
web_idl_database = web_idl_database_outputs[0]
inputs = [ web_idl_database ]
output_data_file = "${root_build_dir}/high_entropy_list.csv"
outputs = [ output_data_file ]
args = [
"--web_idl_database",
rebase_path(web_idl_database, root_build_dir),
"--output",
rebase_path(output_data_file, root_build_dir),
]
deps = [ ":web_idl_database" ]
}
# Exposes the libraries that affect the resulting blob image of the V8 context
# snapshot.
group("v8_context_snapshot_influential_libs") {
......
......@@ -178,6 +178,7 @@ bindings_dir = get_path_info(".", "abspath")
blink_output_dir = "$root_gen_dir/third_party/blink/renderer"
bindings_output_dir = "$root_gen_dir/third_party/blink/renderer/bindings"
bindings_core_v8_output_dir = "$bindings_output_dir/core/v8"
web_idl_database_filepath = "${bindings_output_dir}/web_idl_database.pickle"
bindings_unittest_files =
get_path_info(
......
# Copyright 2020 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.
"""
Generate of table of APIs and their attributes based on the WebIDL database.
The columns of the table are as follows:
* interface : Name of interface.
* name : Member name. Will be empty for interfaces.
* entity_type : One of 'interface', 'namespace', 'const', 'attribute',
'operation', 'constructor', 'stringifier', 'iterable',
'maplike', 'setlike', 'dictionary'
* idl_type : Type of the object. For function-like entries, this is the
type of the return value. Note that the type is stripped
of nullable unions.
* syntactic_form : Human readable idl_type.
* use_counter : If usage is being measured, this is the UseCounter.
* secure_context : 'True' if the [SecureContext] extended attribute is
present. Empty otherwise.
* high_entropy : Value of [HighEntropy] extended attribute. '(True)' if the
[HighEntropy] attribute is present but isn't assigned a
type.
"""
import optparse
from io import BytesIO
from csv import DictWriter
from utilities import write_file
from v8_utilities import capitalize
import web_idl
def parse_options():
parser = optparse.OptionParser(usage="%prog [options]")
parser.add_option("--web_idl_database",
type="string",
help="filepath of the input database")
parser.add_option("--output",
type="string",
help="filepath of output file")
options, args = parser.parse_args()
required_option_names = ("web_idl_database", "output")
for opt_name in required_option_names:
if getattr(options, opt_name) is None:
parser.error("--{} is a required option.".format(opt_name))
return options, args
def get_idl_type_name(idl_type):
assert isinstance(idl_type, web_idl.IdlType)
unwrapped_type = idl_type.unwrap()
return unwrapped_type.type_name, unwrapped_type.syntactic_form
def true_or_nothing(v):
return 'True' if v else ''
def arguments_to_str(args):
serialized_args = []
for arg in args:
type_name, _ = get_idl_type_name(arg.idl_type)
serialized_args.append(type_name)
return '(' + ','.join(serialized_args) + ')'
def record(csv_writer, entity):
interface = ''
name = ''
entity_type = ''
use_counter = ''
secure_context = ''
high_entropy = ''
idl_type = ''
arguments = ''
syntactic_form = ''
source_file = ''
source_line = ''
secure_context = ('SecureContext' in entity.extended_attributes)
if 'HighEntropy' in entity.extended_attributes:
high_entropy = entity.extended_attributes.value_of('HighEntropy')
if not high_entropy:
high_entropy = '(True)'
if 'Measure' in entity.extended_attributes:
use_counter = capitalize(entity.identifier)
if not isinstance(entity, web_idl.Interface):
use_counter = (capitalize(entity.owner.identifier) + '_' +
use_counter)
elif 'MeasureAs' in entity.extended_attributes:
use_counter = entity.extended_attributes.value_of('MeasureAs')
for location in entity.debug_info.all_locations:
if location.line_number:
source_file = location.filepath
source_line = location.line_number
break
if not source_file:
location = entity.debug_info.location
source_file = location.filepath
if isinstance(entity, web_idl.FunctionLike):
arguments = arguments_to_str(entity.arguments)
if isinstance(entity, web_idl.Interface):
interface = entity.identifier
name = ''
entity_type = 'interface'
else:
interface = entity.owner.identifier
name = entity.identifier
if isinstance(entity, web_idl.Attribute):
entity_type = 'attribute'
idl_type, syntactic_form = get_idl_type_name(entity.idl_type)
elif isinstance(entity, web_idl.Operation):
entity_type = 'operation'
idl_type, syntactic_form = get_idl_type_name(entity.return_type)
elif isinstance(entity, web_idl.Constant):
entity_type = 'constant'
idl_type, syntactic_form = get_idl_type_name(entity.idl_type)
else:
assert False, "Unexpected IDL construct"
csv_writer.writerow({
'interface': interface,
'name': name,
'entity_type': entity_type,
'arguments': arguments,
'idl_type': idl_type,
'syntactic_form': syntactic_form,
'use_counter': use_counter,
'secure_context': true_or_nothing(secure_context),
'high_entropy': high_entropy,
'source_file': source_file,
'source_line': source_line
})
def main():
options, _ = parse_options()
with BytesIO() as out_buffer:
csv_writer = DictWriter(out_buffer,
fieldnames=[
'interface', 'name', 'entity_type',
'arguments', 'idl_type', 'syntactic_form',
'use_counter', 'secure_context',
'high_entropy', 'source_file',
'source_line'
])
csv_writer.writeheader()
web_idl_database = web_idl.Database.read_from_file(
options.web_idl_database)
for interface in web_idl_database.interfaces:
record(csv_writer, interface)
for entity in (interface.attributes + interface.operations +
interface.constants):
record(csv_writer, entity)
write_file(out_buffer.getvalue(), options.output)
if __name__ == '__main__':
main()
# Generated by running:
# build/print_python_deps.py --root third_party/blink/renderer/bindings/scripts --output third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.pydeps third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.py
../../../../pyjson5/src/json5/__init__.py
../../../../pyjson5/src/json5/lib.py
../../../../pyjson5/src/json5/parser.py
../../../../pyjson5/src/json5/version.py
../../build/scripts/blinkbuild/__init__.py
../../build/scripts/blinkbuild/name_style_converter.py
generate_high_entropy_list.py
idl_definitions.py
idl_types.py
utilities.py
v8_globals.py
v8_utilities.py
web_idl/__init__.py
web_idl/argument.py
web_idl/ast_group.py
web_idl/attribute.py
web_idl/callback_function.py
web_idl/callback_interface.py
web_idl/code_generator_info.py
web_idl/composition_parts.py
web_idl/constant.py
web_idl/constructor.py
web_idl/database.py
web_idl/database_builder.py
web_idl/dictionary.py
web_idl/enumeration.py
web_idl/exposure.py
web_idl/extended_attribute.py
web_idl/file_io.py
web_idl/function_like.py
web_idl/idl_compiler.py
web_idl/idl_type.py
web_idl/includes.py
web_idl/interface.py
web_idl/ir_builder.py
web_idl/ir_map.py
web_idl/literal_constant.py
web_idl/make_copy.py
web_idl/namespace.py
web_idl/operation.py
web_idl/reference.py
web_idl/runtime_enabled_features.py
web_idl/typedef.py
web_idl/union.py
web_idl/user_defined_type.py
web_idl/validator.py
[style]
based_on_style = pep8
......@@ -4,5 +4,8 @@
group("privacy_budget_tools") {
testonly = true
deps = [ "font_indexer:font_indexer" ]
deps = [
"blink_apis:blink_apis",
"font_indexer:font_indexer",
]
}
# Copyright 2020 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.
import("//build/config/python.gni")
import("//third_party/blink/renderer/bindings/bindings.gni")
import("//third_party/protobuf/proto_library.gni")
proto_library("protos") {
sources = [ "proto/blink_apis.proto" ]
generate_python = true
visibility = [ ":*" ]
}
action("blink_apis") {
testonly = true
script = "generate_blink_api_db.py"
inputs = [
web_idl_database_filepath,
"blink_api_proto.py",
]
output_data_file = "${root_build_dir}/blink_apis.textpb"
outputs = [ output_data_file ]
args = [
"--web_idl_database",
rebase_path(web_idl_database_filepath, root_build_dir),
"--output",
rebase_path(output_data_file, root_build_dir),
"--path",
string_join(":",
[
rebase_path("//third_party/blink/renderer/bindings/scripts",
root_build_dir),
rebase_path("//third_party/blink/renderer/build/scripts",
root_build_dir),
rebase_path("pyproto/tools/privacy_budget/blink_apis/proto",
root_build_dir,
root_out_dir),
rebase_path("pyproto", root_build_dir, root_out_dir),
rebase_path("pyproto/google/third_party/six",
root_build_dir,
root_out_dir),
]),
]
deps = [
":protos",
"//third_party/blink/renderer/bindings:web_idl_database",
"//third_party/protobuf:py_proto_runtime",
]
}
# Copyright 2020 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 __future__ import print_function
from v8_utilities import capitalize
from google.protobuf.text_format import MessageToString
import web_idl
import blink_apis_pb2 as pb
class BlinkApiProto(object):
"""BlinkApiProto converts a WebIdlDatabase to
a identifiability.blink_apis.Snapshot proto defined in
proto/blink_apis.proto"""
def __init__(self, web_idl_pickle, proto_out_file, chromium_revision):
self.web_idl_database = web_idl.Database.read_from_file(web_idl_pickle)
self.proto_out_file = proto_out_file
self.snapshot = pb.Snapshot()
if chromium_revision:
self.snapshot.chromium_revision = chromium_revision
def Parse(self):
"""The main entry point, which synchronously does all the work."""
for interface in self.web_idl_database.interfaces:
self._ConvertIdlInterfaceLike(self.snapshot.interfaces.add(),
interface)
for dictionary in self.web_idl_database.dictionaries:
self._ConvertIdlDictionary(self.snapshot.dictionaries.add(),
dictionary)
for enumeration in self.web_idl_database.enumerations:
self._ConvertIdlEnumeration(self.snapshot.enumerations.add(),
enumeration)
for namespace in self.web_idl_database.namespaces:
self._ConvertIdlInterfaceLike(self.snapshot.namespaces.add(),
namespace)
for function in self.web_idl_database.callback_functions:
self._ConvertIdlOperation(self.snapshot.callback_functions.add(),
function)
for interface in self.web_idl_database.callback_interfaces:
self._ConvertIdlInterfaceLike(
self.snapshot.callback_interfaces.add(), interface)
for typedef in self.web_idl_database.typedefs:
self._ConvertIdlTypedef(self.snapshot.typedefs.add(), typedef)
def WriteTo(self, where):
with open(where, 'w') as f:
f.write(MessageToString(self.snapshot, as_utf8=True))
def _GetHighEntropyType(self, e):
if e is None:
return pb.HIGH_ENTROPY_BENIGN
val = e.values
if not val:
return pb.HIGH_ENTROPY_UNCLASSIFIED
if val[0] == 'Direct':
return pb.HIGH_ENTROPY_DIRECT
assert False, "Unknown HighEntropy value {}".format(val)
def _GetUseCounter(self, parent, measure, measure_as):
if measure_as:
return measure_as.value
if measure:
use_counter = capitalize(parent.identifier)
if not isinstance(parent, web_idl.Interface):
use_counter = (capitalize(parent.owner.identifier) + '_' +
use_counter)
return use_counter
return None
def _ConvertIdlType(self, dest, idl_type):
assert isinstance(idl_type, web_idl.IdlType)
dest.idl_type_string = idl_type.type_name_without_extended_attributes
self._ConvertExtendedAttributes(dest.extended_attributes, idl_type)
# Only look at named definitions. Simple, primitive types don't define
# named identifiers.
depends_on = set()
depends_on.add(idl_type.type_name_without_extended_attributes)
def capture_inner_type(elem):
# All DefinitionType substrates have an 'identifier' field. This
# excludes primitive types like Bool and simple types like Promise.
if hasattr(elem, 'identifier'):
depends_on.add(elem.type_name_without_extended_attributes)
idl_type.apply_to_all_composing_elements(capture_inner_type)
depends_on.remove(idl_type.type_name_without_extended_attributes)
dest.depends_on[:] = list(depends_on)
def _ConvertExtendedAttributes(self, dest, parent):
attr = parent.extended_attributes
assert isinstance(attr, web_idl.ExtendedAttributes)
dest.cross_origin_isolated = ('CrossOriginIsolated' in attr)
if 'Exposed' in attr:
exposed = attr.get('Exposed')
if exposed.has_arguments:
for (i, m) in exposed.arguments:
e = dest.exposed.add()
e.interface = i
e.member = m
elif exposed.has_values:
for v in exposed.values:
e = dest.exposed.add()
e.interface = v
e.member = parent.identifier
setattr(dest, 'global', ('Global' in attr))
dest.same_object = ('SameObject' in attr)
dest.secure_context = ('SecureContext' in attr)
dest.high_entropy = self._GetHighEntropyType(attr.get('HighEntropy'))
if 'Measure' in attr or 'MeasureAs' in attr:
dest.use_counter = self._GetUseCounter(parent, attr.get('Measure'),
attr.get('MeasureAs'))
if 'RuntimeEnabled' in attr:
dest.runtime_enabled = attr.value_of('RuntimeEnabled')
if 'ImplementedAs' in attr:
dest.implemented_as = attr.value_of('ImplementedAs')
def _ConvertIdlAttribute(self, dest, attr):
dest.name = attr.identifier
dest.is_static = attr.is_static
dest.is_readonly = attr.is_readonly
self._ConvertExtendedAttributes(dest.extended_attributes, attr)
self._ConvertIdlType(dest.idl_type, attr.idl_type)
def _GetSpecialOperationType(self, op):
if not isinstance(op, web_idl.Operation):
return pb.SPECIAL_OP_UNSPECIFIED
if op.is_getter:
return pb.SPECIAL_OP_GETTER
if op.is_setter:
return pb.SPECIAL_OP_SETTER
if op.is_stringifier:
return pb.SPECIAL_OP_STRINGIFIER
return pb.SPECIAL_OP_UNSPECIFIED
def _ConvertIdlOperation(self, dest, op):
dest.name = op.identifier
dest.static = op.is_static
dest.special_op_type = self._GetSpecialOperationType(op)
self._ConvertIdlType(dest.return_type, op.return_type)
for arg in op.arguments:
self._ConvertIdlType(dest.arguments.add(), arg.idl_type)
def _ConvertIdlEnumeration(self, dest, enumer):
dest.name = enumer.identifier
dest.values[:] = enumer.values
def _ConvertIdlConstant(self, dest, constant):
dest.name = constant.identifier
dest.value = constant.value.literal
self._ConvertExtendedAttributes(dest.extended_attributes, constant)
self._ConvertIdlType(dest.idl_type, constant.idl_type)
def _ConvertIdlInterfaceLike(self, dest, interface):
dest.name = interface.identifier
if hasattr(interface, 'inherited') and interface.inherited:
dest.inherits_from = interface.inherited.identifier
self._ConvertExtendedAttributes(dest.extended_attributes, interface)
for attr in interface.attributes:
self._ConvertIdlAttribute(dest.attributes.add(), attr)
for op in interface.operations:
self._ConvertIdlOperation(dest.operations.add(), op)
for constant in interface.constants:
self._ConvertIdlConstant(dest.constants.add(), constant)
def _ConvertDictionaryMember(self, dest, member):
assert isinstance(member, web_idl.DictionaryMember)
dest.name = member.identifier
self._ConvertExtendedAttributes(dest.extended_attributes, member)
self._ConvertIdlType(dest.idl_type, member.idl_type)
def _ConvertIdlDictionary(self, dest, dictionary):
assert isinstance(dictionary, web_idl.Dictionary)
dest.name = dictionary.identifier
if dictionary.inherited:
dest.inherits_from = dictionary.inherited.identifier
for member in dictionary.members:
self._ConvertDictionaryMember(dest.members.add(), member)
def _ConvertIdlTypedef(self, dest, typedef):
assert isinstance(typedef, web_idl.Typedef)
dest.name = typedef.identifier
self._ConvertIdlType(dest.idl_type, typedef.idl_type)
#!/usr/bin/env python3
# Copyright 2020 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.
"""
Generate a database of Blink APIs.
The schema is described in proto/blink_apis.proto. It has the following goals:
* Capture enough information to follow the transitive dependencies of an API.
For example if a certain dictionary contains a known identifiable datum,
then any attribute or operation returning this dictionary should also be
considered sensitive.
* Capture identifiability annotations and other relevant bits of information
in the form of Extended Attributes.
* Be a method for keeping track of how APIs are introduced, updated, and
removed.
* Be a method for looking up which APIs correspond to a `UseCounter`.
* Be a method for looking up the APIs that are affected by a runtime feature.
To generate this API DB, run the following in a Chromium build directory:
ninja blink_apis
This should create a file named `blink_apis.textpb` in the root build
directory. E.g. 'out/Debug'`
"""
import sys
import argparse
def parse_options():
parser = argparse.ArgumentParser(description="%prog [options]")
parser.add_argument("--web_idl_database",
type=str,
help="filepath of the input database")
parser.add_argument("--output", type=str, help="filepath of output file")
parser.add_argument("--path", type=str, help="Additions to sys.path")
parser.add_argument(
"--chromium_revision",
type=str,
help="Chromium revision (git hash) for the source of Blink WebIDL DB")
args = parser.parse_args()
required_option_names = ("web_idl_database", "output")
for opt_name in required_option_names:
if getattr(args, opt_name) is None:
parser.error("--{} is a required option.".format(opt_name))
if args.path:
for p in args.path.split(':'):
sys.path.append(p)
return args
def main():
args = parse_options()
from blink_api_proto import BlinkApiProto
p = BlinkApiProto(args.web_idl_database, args.output,
args.chromium_revision)
p.Parse()
p.WriteTo(args.output)
if __name__ == '__main__':
main()
// Copyright 2020 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.
syntax = "proto3";
package identifiability.blink_apis;
message Snapshot {
string chromium_revision = 1;
repeated InterfaceLike interfaces = 2;
repeated InterfaceLike namespaces = 3;
repeated Dictionary dictionaries = 4;
repeated Enumeration enumerations = 5;
repeated Operation callback_functions = 6;
repeated InterfaceLike callback_interfaces = 7;
repeated Typedef typedefs = 8;
}
// Type of HighEntropy.
enum HighEntropyType {
// Invalid value. Means that the field is uninitialized.
HIGH_ENTROPY_UNSPECIFIED = 0;
// Not a source of identifiable information.
HIGH_ENTROPY_BENIGN = 1;
// A source of identifiable information. But the surface doesn't have
// a classification.
HIGH_ENTROPY_UNCLASSIFIED = 2;
// A source of identifiable information. The mapping from the inputs to the
// output of the annotated API directly conveys the identifiable information.
HIGH_ENTROPY_DIRECT = 3;
}
// Includes both WebIDL defined extended attributes as well as Chromium specific
// custom extended attributes.
//
// The latter are described in:
// https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/bindings/IDLExtendedAttributes.md
message ExtendedAttributes {
// https://heycam.github.io/webidl/#CrossOriginIsolated
bool cross_origin_isolated = 1;
message Exposed {
string interface = 1;
string member = 2;
}
// https://heycam.github.io/webidl/#Exposed
repeated Exposed exposed =
2; // One value for each interface/partial interface/etc..
// https://heycam.github.io/webidl/#Global
bool global = 3;
// https://heycam.github.io/webidl/#SameObject
bool same_object = 4;
// https://heycam.github.io/webidl/#SecureContext
bool secure_context = 5;
// https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/bindings/IDLExtendedAttributes.md#HighEntropy_m_a_c
// Ideally this must always be one of the well defined values. However, the
// HIGH_ENTROPY_UNSPECIFIED value should also be interpreted as
// NOT_HIGH_ENTROPY.
HighEntropyType high_entropy = 6;
// Value of MeasureAs or the autogenerated use counter value. Empty or
// undefined string is equivalent to no use counter.
//
// https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/bindings/IDLExtendedAttributes.md#measure_i_m_a_c
string use_counter = 7;
// Value of [RuntimeEnabled]
// https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/bindings/IDLExtendedAttributes.md#runtimeenabled_i_m_a_c
// Empty or undefined string is equivalent to there not being
// a `RuntimeEnabled` attribute.
string runtime_enabled = 8;
// Cross origin exposure. The [CrossOrigin=(Setter)] and
// [CrossOrigin=(Getter)] options are separated out into two distinct booleans
// for easier access.
// https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/bindings/IDLExtendedAttributes.md#crossorigin_m_a
bool cross_origin_getter = 9;
bool cross_origin_setter = 10;
// https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/bindings/IDLExtendedAttributes.md#implementedas_i_m_s_a
// Empty or undefined string is equivalent to an absent [ImplementedAs]
// attribute.
string implemented_as = 11;
}
// Represents an interface [^1], mixins or partial interface [^2], callback
// interface [^3], or namespace [^4].
//
// [^1]: https://heycam.github.io/webidl/#idl-interfaces
// [^2]: https://heycam.github.io/webidl/#idl-interface-mixins
// [^3]: https://heycam.github.io/webidl/#idl-callback-interfaces
// [^4]: https://heycam.github.io/webidl/#idl-namespaces
message InterfaceLike {
// Must be non-empty and must satisfy the requirements outlined in
// https://heycam.github.io/webidl/#idl-names . This should be trivially
// satisfied for all valid WebIDLs in the Chromium tree.
string name = 1;
// If this interface is defined to inherit from another interface, the latter
// is described here. Empty or undefined strings are interpreted as meaning
// that the interface does not inherit from another.
string inherits_from = 2;
// Extended attributes for the interface. Some may percolate down to the
// members.
ExtendedAttributes extended_attributes = 3;
// Members
repeated Attribute attributes = 4;
repeated Operation operations = 5;
repeated Constant constants = 6;
}
message IDLType {
// This is the string representation of the type. E.g.: "unsigned long long"
// or "sequence<USVString>" or somesuch. For this database, we leave out a lot
// of detail which should still be available in this field.
//
// The contents of this field is expected to parse as the _Type_ production in
// the WebIDL spec [^1]. The string may contain references to unresolved
// typedefs.
//
// [1]: https://heycam.github.io/webidl/#prod-Type
string idl_type_string = 1;
// Each `depends_on` value is string containing an identifier that maps to
// another `Interface` or `Dictionary` that's defined in the same snapshot.
//
// For example: "( boolean or sequence<Foo> or Bar )" depends on "Foo" and
// "Bar" types. It also depends on "boolean" but that's a primitive type
// that's not interesting for this database.
//
// All such dependent types must be listed for each type after resolving
// typedefs.
repeated string depends_on = 2;
// Types can have these too. Though none of the attributes we are interested
// in are likely to show up.
ExtendedAttributes extended_attributes = 3;
}
// An ordered map.
// https://heycam.github.io/webidl/#idl-dictionaries
message Dictionary {
// Name of the dictionary.
string name = 1;
string inherits_from = 2;
// Dictionary member.
// https://heycam.github.io/webidl/#dfn-dictionary-member
message Member {
string name = 1;
ExtendedAttributes extended_attributes = 2;
IDLType idl_type = 3;
}
repeated Member members = 7;
}
// Special operation types.
// https://heycam.github.io/webidl/#dfn-special-operation
enum SpecialOperationType {
SPECIAL_OP_UNSPECIFIED = 0; // Operation is not special.
SPECIAL_OP_GETTER = 1; // https://heycam.github.io/webidl/#dfn-getter
SPECIAL_OP_SETTER = 2; // https://heycam.github.io/webidl/#dfn-setter
SPECIAL_OP_STRINGIFIER =
3; // https://heycam.github.io/webidl/#dfn-stringifier
}
// An Operation represents an interface member, callback interface member, or
// namespace member.
// https://heycam.github.io/webidl/#idl-operations
message Operation {
string name = 1;
ExtendedAttributes extended_attributes = 2;
IDLType return_type = 3;
repeated IDLType arguments = 4;
// True for static operations.
// https://heycam.github.io/webidl/#dfn-static-operation
bool static = 9;
// The following fields are only applicable to special operations.
// https://heycam.github.io/webidl/#dfn-special-operation
SpecialOperationType special_op_type = 5;
}
// An interface member or a namespace member declaring a data field.
// https://heycam.github.io/webidl/#dfn-attribute
message Attribute {
string name = 1;
ExtendedAttributes extended_attributes = 2;
IDLType idl_type = 3;
bool is_static = 4;
bool is_readonly = 5;
}
// A declaration binding a value to a name.
// https://heycam.github.io/webidl/#dfn-attribute
message Constant {
string name = 1;
ExtendedAttributes extended_attributes = 2;
IDLType idl_type = 3;
// Textual serialization of the value. Should be interpreted as befitting
// `type`. There should be no expectation that this representation is
// unambiguously parsable. It's intended solely for human consumption.
string value = 4;
}
// Defines a type who's valid values are a set of strings.
// https://heycam.github.io/webidl/#dfn-enumeration
message Enumeration {
string name = 1;
// Enum values are strings.
repeated string values = 2;
}
// Declares a new name for a type.
// https://heycam.github.io/webidl/#dfn-typedef
// These are included for completeness.
message Typedef {
string name = 1;
IDLType idl_type = 2;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment