summaryrefslogtreecommitdiff
path: root/utils/ipc/mojo/public/tools/mojom/mojom
diff options
context:
space:
mode:
authorPaul Elder <paul.elder@ideasonboard.com>2020-09-08 20:47:19 +0900
committerPaul Elder <paul.elder@ideasonboard.com>2021-05-26 13:03:27 +0900
commit139d8855747799da9218f36720004fb1927bd2ef (patch)
tree7f3f47e68e08cfcf19ee9f37cc91f31690b9fc53 /utils/ipc/mojo/public/tools/mojom/mojom
parenta7ded8e8f5dd0ae0841960280fe9a7107f945a34 (diff)
utils: ipc: Update mojo
Update mojo from the Chromium repository. The commit from which this was taken is: 9c138d992bfc1fb8f4f7bcf58d00bf19c219e4e2 "Updating trunk VERSION from 4523.0 to 4524.0" The update-mojo.sh script was used for this update. Bug: https://bugs.libcamera.org/show_bug.cgi?id=34 Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'utils/ipc/mojo/public/tools/mojom/mojom')
-rw-r--r--utils/ipc/mojo/public/tools/mojom/mojom/BUILD.gn1
-rw-r--r--utils/ipc/mojo/public/tools/mojom/mojom/generate/generator.py14
-rw-r--r--utils/ipc/mojo/public/tools/mojom/mojom/generate/module.py163
-rw-r--r--utils/ipc/mojo/public/tools/mojom/mojom/generate/template_expander.py11
-rw-r--r--utils/ipc/mojo/public/tools/mojom/mojom/generate/translate.py26
5 files changed, 175 insertions, 40 deletions
diff --git a/utils/ipc/mojo/public/tools/mojom/mojom/BUILD.gn b/utils/ipc/mojo/public/tools/mojom/mojom/BUILD.gn
index 7416ef19..51facc0c 100644
--- a/utils/ipc/mojo/public/tools/mojom/mojom/BUILD.gn
+++ b/utils/ipc/mojo/public/tools/mojom/mojom/BUILD.gn
@@ -8,7 +8,6 @@ group("mojom") {
"error.py",
"fileutil.py",
"generate/__init__.py",
- "generate/constant_resolver.py",
"generate/generator.py",
"generate/module.py",
"generate/pack.py",
diff --git a/utils/ipc/mojo/public/tools/mojom/mojom/generate/generator.py b/utils/ipc/mojo/public/tools/mojom/mojom/generate/generator.py
index de62260a..4a1c73fc 100644
--- a/utils/ipc/mojo/public/tools/mojom/mojom/generate/generator.py
+++ b/utils/ipc/mojo/public/tools/mojom/mojom/generate/generator.py
@@ -136,9 +136,14 @@ class Stylizer(object):
def WriteFile(contents, full_path):
# If |contents| is same with the file content, we skip updating.
+ if not isinstance(contents, bytes):
+ data = contents.encode('utf8')
+ else:
+ data = contents
+
if os.path.isfile(full_path):
with open(full_path, 'rb') as destination_file:
- if destination_file.read() == contents:
+ if destination_file.read() == data:
return
# Make sure the containing directory exists.
@@ -146,11 +151,8 @@ def WriteFile(contents, full_path):
fileutil.EnsureDirectoryExists(full_dir)
# Dump the data to disk.
- with open(full_path, "wb") as f:
- if not isinstance(contents, bytes):
- f.write(contents.encode('utf-8'))
- else:
- f.write(contents)
+ with open(full_path, 'wb') as f:
+ f.write(data)
def AddComputedData(module):
diff --git a/utils/ipc/mojo/public/tools/mojom/mojom/generate/module.py b/utils/ipc/mojo/public/tools/mojom/mojom/generate/module.py
index 8547ff64..9bdb28e0 100644
--- a/utils/ipc/mojo/public/tools/mojom/mojom/generate/module.py
+++ b/utils/ipc/mojo/public/tools/mojom/mojom/generate/module.py
@@ -12,7 +12,33 @@
# method = interface.AddMethod('Tat', 0)
# method.AddParameter('baz', 0, mojom.INT32)
-import pickle
+import sys
+if sys.version_info.major == 2:
+ import cPickle as pickle
+else:
+ import pickle
+from uuid import UUID
+
+
+class BackwardCompatibilityChecker(object):
+ """Used for memoization while recursively checking two type definitions for
+ backward-compatibility."""
+
+ def __init__(self):
+ self._cache = {}
+
+ def IsBackwardCompatible(self, new_kind, old_kind):
+ key = (new_kind, old_kind)
+ result = self._cache.get(key)
+ if result is None:
+ # Assume they're compatible at first to effectively ignore recursive
+ # checks between these types, e.g. if both kinds are a struct or union
+ # that references itself in a field.
+ self._cache[key] = True
+ result = new_kind.IsBackwardCompatible(old_kind, self)
+ self._cache[key] = result
+ return result
+
# We use our own version of __repr__ when displaying the AST, as the
# AST currently doesn't capture which nodes are reference (e.g. to
@@ -114,6 +140,10 @@ class Kind(object):
# during a subsequent run of the parser.
return hash((self.spec, self.parent_kind))
+ # pylint: disable=unused-argument
+ def IsBackwardCompatible(self, rhs, checker):
+ return self == rhs
+
class ReferenceKind(Kind):
"""ReferenceKind represents pointer and handle types.
@@ -195,6 +225,10 @@ class ReferenceKind(Kind):
def __hash__(self):
return hash((super(ReferenceKind, self).__hash__(), self.is_nullable))
+ def IsBackwardCompatible(self, rhs, checker):
+ return (super(ReferenceKind, self).IsBackwardCompatible(rhs, checker)
+ and self.is_nullable == rhs.is_nullable)
+
# Initialize the set of primitive types. These can be accessed by clients.
BOOL = Kind('b')
@@ -253,9 +287,13 @@ PRIMITIVES = (
)
ATTRIBUTE_MIN_VERSION = 'MinVersion'
+ATTRIBUTE_DEFAULT = 'Default'
ATTRIBUTE_EXTENSIBLE = 'Extensible'
+ATTRIBUTE_NO_INTERRUPT = 'NoInterrupt'
ATTRIBUTE_STABLE = 'Stable'
ATTRIBUTE_SYNC = 'Sync'
+ATTRIBUTE_UNLIMITED_SIZE = 'UnlimitedSize'
+ATTRIBUTE_UUID = 'Uuid'
class NamedValue(object):
@@ -274,6 +312,9 @@ class NamedValue(object):
and (self.parent_kind, self.mojom_name) == (rhs.parent_kind,
rhs.mojom_name))
+ def __hash__(self):
+ return hash((self.parent_kind, self.mojom_name))
+
class BuiltinValue(object):
def __init__(self, value):
@@ -368,21 +409,19 @@ class Field(object):
class StructField(Field):
- pass
+ def __hash__(self):
+ return super(Field, self).__hash__()
class UnionField(Field):
pass
-def _IsFieldBackwardCompatible(new_field, old_field):
+def _IsFieldBackwardCompatible(new_field, old_field, checker):
if (new_field.min_version or 0) != (old_field.min_version or 0):
return False
- if isinstance(new_field.kind, (Enum, Struct, Union)):
- return new_field.kind.IsBackwardCompatible(old_field.kind)
-
- return new_field.kind == old_field.kind
+ return checker.IsBackwardCompatible(new_field.kind, old_field.kind)
class Struct(ReferenceKind):
@@ -457,7 +496,7 @@ class Struct(ReferenceKind):
for constant in self.constants:
constant.Stylize(stylizer)
- def IsBackwardCompatible(self, older_struct):
+ def IsBackwardCompatible(self, older_struct, checker):
"""This struct is backward-compatible with older_struct if and only if all
of the following conditions hold:
- Any newly added field is tagged with a [MinVersion] attribute specifying
@@ -496,7 +535,7 @@ class Struct(ReferenceKind):
old_field = old_fields[ordinal]
if (old_field.min_version or 0) > max_old_min_version:
max_old_min_version = old_field.min_version
- if not _IsFieldBackwardCompatible(new_field, old_field):
+ if not _IsFieldBackwardCompatible(new_field, old_field, checker):
# Type or min-version mismatch between old and new versions of the same
# ordinal field.
return False
@@ -590,7 +629,7 @@ class Union(ReferenceKind):
for field in self.fields:
field.Stylize(stylizer)
- def IsBackwardCompatible(self, older_union):
+ def IsBackwardCompatible(self, older_union, checker):
"""This union is backward-compatible with older_union if and only if all
of the following conditions hold:
- Any newly added field is tagged with a [MinVersion] attribute specifying
@@ -623,7 +662,7 @@ class Union(ReferenceKind):
if not new_field:
# A field was removed, which is not OK.
return False
- if not _IsFieldBackwardCompatible(new_field, old_field):
+ if not _IsFieldBackwardCompatible(new_field, old_field, checker):
# An field changed its type or MinVersion, which is not OK.
return False
old_min_version = old_field.min_version or 0
@@ -703,6 +742,10 @@ class Array(ReferenceKind):
def __hash__(self):
return id(self)
+ def IsBackwardCompatible(self, rhs, checker):
+ return (isinstance(rhs, Array) and self.length == rhs.length
+ and checker.IsBackwardCompatible(self.kind, rhs.kind))
+
class Map(ReferenceKind):
"""A map.
@@ -747,6 +790,11 @@ class Map(ReferenceKind):
def __hash__(self):
return id(self)
+ def IsBackwardCompatible(self, rhs, checker):
+ return (isinstance(rhs, Map)
+ and checker.IsBackwardCompatible(self.key_kind, rhs.key_kind)
+ and checker.IsBackwardCompatible(self.value_kind, rhs.value_kind))
+
class PendingRemote(ReferenceKind):
ReferenceKind.AddSharedProperty('kind')
@@ -768,6 +816,10 @@ class PendingRemote(ReferenceKind):
def __hash__(self):
return id(self)
+ def IsBackwardCompatible(self, rhs, checker):
+ return (isinstance(rhs, PendingRemote)
+ and checker.IsBackwardCompatible(self.kind, rhs.kind))
+
class PendingReceiver(ReferenceKind):
ReferenceKind.AddSharedProperty('kind')
@@ -789,6 +841,10 @@ class PendingReceiver(ReferenceKind):
def __hash__(self):
return id(self)
+ def IsBackwardCompatible(self, rhs, checker):
+ return isinstance(rhs, PendingReceiver) and checker.IsBackwardCompatible(
+ self.kind, rhs.kind)
+
class PendingAssociatedRemote(ReferenceKind):
ReferenceKind.AddSharedProperty('kind')
@@ -810,6 +866,11 @@ class PendingAssociatedRemote(ReferenceKind):
def __hash__(self):
return id(self)
+ def IsBackwardCompatible(self, rhs, checker):
+ return isinstance(rhs,
+ PendingAssociatedRemote) and checker.IsBackwardCompatible(
+ self.kind, rhs.kind)
+
class PendingAssociatedReceiver(ReferenceKind):
ReferenceKind.AddSharedProperty('kind')
@@ -831,6 +892,11 @@ class PendingAssociatedReceiver(ReferenceKind):
def __hash__(self):
return id(self)
+ def IsBackwardCompatible(self, rhs, checker):
+ return isinstance(
+ rhs, PendingAssociatedReceiver) and checker.IsBackwardCompatible(
+ self.kind, rhs.kind)
+
class InterfaceRequest(ReferenceKind):
ReferenceKind.AddSharedProperty('kind')
@@ -851,6 +917,10 @@ class InterfaceRequest(ReferenceKind):
def __hash__(self):
return id(self)
+ def IsBackwardCompatible(self, rhs, checker):
+ return isinstance(rhs, InterfaceRequest) and checker.IsBackwardCompatible(
+ self.kind, rhs.kind)
+
class AssociatedInterfaceRequest(ReferenceKind):
ReferenceKind.AddSharedProperty('kind')
@@ -873,6 +943,11 @@ class AssociatedInterfaceRequest(ReferenceKind):
def __hash__(self):
return id(self)
+ def IsBackwardCompatible(self, rhs, checker):
+ return isinstance(
+ rhs, AssociatedInterfaceRequest) and checker.IsBackwardCompatible(
+ self.kind, rhs.kind)
+
class Parameter(object):
def __init__(self,
@@ -976,6 +1051,16 @@ class Method(object):
return self.attributes.get(ATTRIBUTE_SYNC) \
if self.attributes else None
+ @property
+ def allow_interrupt(self):
+ return not self.attributes.get(ATTRIBUTE_NO_INTERRUPT) \
+ if self.attributes else True
+
+ @property
+ def unlimited_message_size(self):
+ return self.attributes.get(ATTRIBUTE_UNLIMITED_SIZE) \
+ if self.attributes else False
+
def __eq__(self, rhs):
return (isinstance(rhs, Method) and
(self.mojom_name, self.ordinal, self.parameters,
@@ -1029,7 +1114,7 @@ class Interface(ReferenceKind):
for constant in self.constants:
constant.Stylize(stylizer)
- def IsBackwardCompatible(self, older_interface):
+ def IsBackwardCompatible(self, older_interface, checker):
"""This interface is backward-compatible with older_interface if and only
if all of the following conditions hold:
- All defined methods in older_interface (when identified by ordinal) have
@@ -1067,8 +1152,8 @@ class Interface(ReferenceKind):
# A method was removed, which is not OK.
return False
- if not new_method.param_struct.IsBackwardCompatible(
- old_method.param_struct):
+ if not checker.IsBackwardCompatible(new_method.param_struct,
+ old_method.param_struct):
# The parameter list is not backward-compatible, which is not OK.
return False
@@ -1081,8 +1166,8 @@ class Interface(ReferenceKind):
if new_method.response_param_struct is None:
# A reply was removed from a message, which is not OK.
return False
- if not new_method.response_param_struct.IsBackwardCompatible(
- old_method.response_param_struct):
+ if not checker.IsBackwardCompatible(new_method.response_param_struct,
+ old_method.response_param_struct):
# The new message's reply is not backward-compatible with the old
# message's reply, which is not OK.
return False
@@ -1120,6 +1205,20 @@ class Interface(ReferenceKind):
self.attributes) == (rhs.mojom_name, rhs.methods, rhs.enums,
rhs.constants, rhs.attributes))
+ @property
+ def uuid(self):
+ uuid_str = self.attributes.get(ATTRIBUTE_UUID) if self.attributes else None
+ if uuid_str is None:
+ return None
+
+ try:
+ u = UUID(uuid_str)
+ except:
+ raise ValueError('Invalid format for Uuid attribute on interface {}. '
+ 'Expected standard RFC 4122 string representation of '
+ 'a UUID.'.format(self.mojom_name))
+ return (int(u.hex[:16], 16), int(u.hex[16:], 16))
+
def __hash__(self):
return id(self)
@@ -1144,6 +1243,11 @@ class AssociatedInterface(ReferenceKind):
def __hash__(self):
return id(self)
+ def IsBackwardCompatible(self, rhs, checker):
+ return isinstance(rhs,
+ AssociatedInterface) and checker.IsBackwardCompatible(
+ self.kind, rhs.kind)
+
class EnumField(object):
def __init__(self,
@@ -1161,6 +1265,11 @@ class EnumField(object):
self.name = stylizer.StylizeEnumField(self.mojom_name)
@property
+ def default(self):
+ return self.attributes.get(ATTRIBUTE_DEFAULT, False) \
+ if self.attributes else False
+
+ @property
def min_version(self):
return self.attributes.get(ATTRIBUTE_MIN_VERSION) \
if self.attributes else None
@@ -1186,6 +1295,7 @@ class Enum(Kind):
self.attributes = attributes
self.min_value = None
self.max_value = None
+ self.default_field = None
def Repr(self, as_ref=True):
if as_ref:
@@ -1216,7 +1326,8 @@ class Enum(Kind):
prefix = self.module.GetNamespacePrefix()
return '%s%s' % (prefix, self.mojom_name)
- def IsBackwardCompatible(self, older_enum):
+ # pylint: disable=unused-argument
+ def IsBackwardCompatible(self, older_enum, checker):
"""This enum is backward-compatible with older_enum if and only if one of
the following conditions holds:
- Neither enum is [Extensible] and both have the exact same set of valid
@@ -1250,9 +1361,10 @@ class Enum(Kind):
def __eq__(self, rhs):
return (isinstance(rhs, Enum) and
(self.mojom_name, self.native_only, self.fields, self.attributes,
- self.min_value,
- self.max_value) == (rhs.mojom_name, rhs.native_only, rhs.fields,
- rhs.attributes, rhs.min_value, rhs.max_value))
+ self.min_value, self.max_value,
+ self.default_field) == (rhs.mojom_name, rhs.native_only,
+ rhs.fields, rhs.attributes, rhs.min_value,
+ rhs.max_value, rhs.default_field))
def __hash__(self):
return id(self)
@@ -1272,6 +1384,7 @@ class Module(object):
self.attributes = attributes
self.imports = []
self.imported_kinds = {}
+ self.metadata = {}
def __repr__(self):
# Gives us a decent __repr__ for modules.
@@ -1285,6 +1398,9 @@ class Module(object):
rhs.imports, rhs.constants, rhs.enums,
rhs.structs, rhs.unions, rhs.interfaces))
+ def __hash__(self):
+ return id(self)
+
def Repr(self, as_ref=True):
if as_ref:
return '<%s path=%r mojom_namespace=%r>' % (
@@ -1555,6 +1671,13 @@ def HasSyncMethods(interface):
return False
+def HasUninterruptableMethods(interface):
+ for method in interface.methods:
+ if not method.allow_interrupt:
+ return True
+ return False
+
+
def ContainsHandlesOrInterfaces(kind):
"""Check if the kind contains any handles.
diff --git a/utils/ipc/mojo/public/tools/mojom/mojom/generate/template_expander.py b/utils/ipc/mojo/public/tools/mojom/mojom/generate/template_expander.py
index 7a300560..0da90058 100644
--- a/utils/ipc/mojo/public/tools/mojom/mojom/generate/template_expander.py
+++ b/utils/ipc/mojo/public/tools/mojom/mojom/generate/template_expander.py
@@ -75,9 +75,8 @@ def PrecompileTemplates(generator_modules, output_dir):
os.path.dirname(module.__file__), generator.GetTemplatePrefix())
]))
jinja_env.filters.update(generator.GetFilters())
- jinja_env.compile_templates(
- os.path.join(output_dir, "%s.zip" % generator.GetTemplatePrefix()),
- extensions=["tmpl"],
- zip="stored",
- py_compile=True,
- ignore_errors=False)
+ jinja_env.compile_templates(os.path.join(
+ output_dir, "%s.zip" % generator.GetTemplatePrefix()),
+ extensions=["tmpl"],
+ zip="stored",
+ ignore_errors=False)
diff --git a/utils/ipc/mojo/public/tools/mojom/mojom/generate/translate.py b/utils/ipc/mojo/public/tools/mojom/mojom/generate/translate.py
index d6df3ca6..7580b780 100644
--- a/utils/ipc/mojo/public/tools/mojom/mojom/generate/translate.py
+++ b/utils/ipc/mojo/public/tools/mojom/mojom/generate/translate.py
@@ -472,6 +472,9 @@ def _Method(module, parsed_method, interface):
"attribute. If no response parameters are needed, you "
"could use an empty response parameter list, i.e., "
"\"=> ()\".")
+ # And only methods with the [Sync] attribute can specify [NoInterrupt].
+ if not method.allow_interrupt and not method.sync:
+ raise Exception("Only [Sync] methods can be marked [NoInterrupt].")
return method
@@ -592,6 +595,16 @@ def _Enum(module, parsed_enum, parent_kind):
map(lambda field: _EnumField(module, enum, field),
parsed_enum.enum_value_list))
_ResolveNumericEnumValues(enum)
+ # TODO(https://crbug.com/731893): Require a default value to be
+ # specified.
+ for field in enum.fields:
+ if field.default:
+ if not enum.extensible:
+ raise Exception('Non-extensible enums may not specify a default')
+ if enum.default_field is not None:
+ raise Exception(
+ 'Only one enumerator value may be specified as the default')
+ enum.default_field = field
module.kinds[enum.spec] = enum
@@ -650,7 +663,9 @@ def _CollectReferencedKinds(module, all_defined_kinds):
if mojom.IsMapKind(kind):
return (extract_referenced_user_kinds(kind.key_kind) +
extract_referenced_user_kinds(kind.value_kind))
- if mojom.IsInterfaceRequestKind(kind) or mojom.IsAssociatedKind(kind):
+ if (mojom.IsInterfaceRequestKind(kind) or mojom.IsAssociatedKind(kind)
+ or mojom.IsPendingRemoteKind(kind)
+ or mojom.IsPendingReceiverKind(kind)):
return [kind.kind]
if mojom.IsStructKind(kind):
return [kind]
@@ -678,12 +693,9 @@ def _CollectReferencedKinds(module, all_defined_kinds):
for method in interface.methods:
for param in itertools.chain(method.parameters or [],
method.response_parameters or []):
- if (mojom.IsStructKind(param.kind) or mojom.IsUnionKind(param.kind)
- or mojom.IsEnumKind(param.kind)
- or mojom.IsAnyInterfaceKind(param.kind)):
- for referenced_kind in extract_referenced_user_kinds(param.kind):
- sanitized_kind = sanitize_kind(referenced_kind)
- referenced_user_kinds[sanitized_kind.spec] = sanitized_kind
+ for referenced_kind in extract_referenced_user_kinds(param.kind):
+ sanitized_kind = sanitize_kind(referenced_kind)
+ referenced_user_kinds[sanitized_kind.spec] = sanitized_kind
return referenced_user_kinds