Commit 8b7bb580 authored by Ken Rockot's avatar Ken Rockot Committed by Commit Bot

Mojo: Introduce [Uuid] attribute

This allows interfaces to be tagged with a UUID within mojom files.
The UUID is propagated to a base::Token constant nested within the
generated interface class for C++ bindings.

This allows consumers to establish stable runtime identifiers for
interfaces that can persist independently from other interface
details, including the superficial name of the definition.

Bug: 1136652
Change-Id: Ib69bc116015606e029a02a663a578e08b0755e78
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2462378Reviewed-by: default avatarDarin Fisher <darin@chromium.org>
Reviewed-by: default avatarErik Chen <erikchen@chromium.org>
Commit-Queue: Ken Rockot <rockot@google.com>
Cr-Commit-Position: refs/heads/master@{#815663}
parent d2cbe7ce
...@@ -28,6 +28,7 @@ source_set("tests") { ...@@ -28,6 +28,7 @@ source_set("tests") {
"handle_passing_unittest.cc", "handle_passing_unittest.cc",
"hash_unittest.cc", "hash_unittest.cc",
"idle_tracking_unittest.cc", "idle_tracking_unittest.cc",
"interface_unittest.cc",
"lazy_serialization_unittest.cc", "lazy_serialization_unittest.cc",
"map_unittest.cc", "map_unittest.cc",
"message_queue.cc", "message_queue.cc",
...@@ -154,6 +155,7 @@ mojom("test_mojom") { ...@@ -154,6 +155,7 @@ mojom("test_mojom") {
"enum_headers_unittest.test-mojom", "enum_headers_unittest.test-mojom",
"flush_async_unittest.test-mojom", "flush_async_unittest.test-mojom",
"idle_tracking_unittest.test-mojom", "idle_tracking_unittest.test-mojom",
"interface_unittest.test-mojom",
"receiver_unittest.test-mojom", "receiver_unittest.test-mojom",
"remote_unittest.test-mojom", "remote_unittest.test-mojom",
"service_factory_unittest.test-mojom", "service_factory_unittest.test-mojom",
......
// 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.
#include "mojo/public/cpp/bindings/tests/interface_unittest.test-mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace mojo {
namespace test {
namespace interface_unittest {
namespace {
using InterfaceTest = ::testing::Test;
TEST(InterfaceTest, Uuid) {
constexpr base::Token kExpectedId{0x51e24935100f474eULL,
0x90f155354bf92a00ULL};
EXPECT_EQ(kExpectedId, mojom::VeryCoolInterface::Uuid_);
}
} // namespace
} // namespace interface_unittest
} // namespace test
} // namespace mojo
// 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.
module mojo.test.interface_unittest.mojom;
[Uuid="51e24935-100f-474e-90f1-55354bf92a00"]
interface VeryCoolInterface {
DoesNotMatter();
};
...@@ -418,6 +418,13 @@ interesting attributes supported today. ...@@ -418,6 +418,13 @@ interesting attributes supported today.
strict presubmit check. See [Versioning](#Versioning) for more details on strict presubmit check. See [Versioning](#Versioning) for more details on
backward-compatibility constraints. backward-compatibility constraints.
**`[Uuid=<UUID>]`**
: Specifies a UUID to be associated with a given interface. The UUID is
intended to remain stable across all changes to the interface definition,
including name changes. The value given for this attribute should be a
standard UUID string representation as specified by RFC 4122. New UUIDs can
be generated with common tools such as `uuidgen`.
**`[EnableIf=value]`** **`[EnableIf=value]`**
: The `EnableIf` attribute is used to conditionally enable definitions when : The `EnableIf` attribute is used to conditionally enable definitions when
the mojom is parsed. If the `mojom` target in the GN file does not include the mojom is parsed. If the `mojom` target in the GN file does not include
......
...@@ -16,6 +16,10 @@ class {{export_attribute}} {{interface.name}} ...@@ -16,6 +16,10 @@ class {{export_attribute}} {{interface.name}}
: public {{interface.name}}InterfaceBase { : public {{interface.name}}InterfaceBase {
public: public:
static const char Name_[]; static const char Name_[];
{%- if interface.uuid %}
static constexpr base::Token Uuid_{ {{interface.uuid[0]}}ULL,
{{interface.uuid[1]}}ULL };
{%- endif %}
static constexpr uint32_t Version_ = {{interface.version}}; static constexpr uint32_t Version_ = {{interface.version}};
static constexpr bool PassesAssociatedKinds_ = {% if interface|passes_associated_kinds %}true{% else %}false{% endif %}; static constexpr bool PassesAssociatedKinds_ = {% if interface|passes_associated_kinds %}true{% else %}false{% endif %};
static constexpr bool HasSyncMethods_ = {% if interface|has_sync_methods %}true{% else %}false{% endif %}; static constexpr bool HasSyncMethods_ = {% if interface|has_sync_methods %}true{% else %}false{% endif %};
......
...@@ -32,6 +32,9 @@ std::move(p_{{param.name}}) ...@@ -32,6 +32,9 @@ std::move(p_{{param.name}})
{#--- Begin #} {#--- Begin #}
const char {{class_name}}::Name_[] = "{{module_namespace}}.{{class_name}}"; const char {{class_name}}::Name_[] = "{{module_namespace}}.{{class_name}}";
{%- if interface.uuid %}
constexpr base::Token {{class_name}}::Uuid_;
{%- endif %}
{#--- Constants #} {#--- Constants #}
{%- for constant in interface.constants %} {%- for constant in interface.constants %}
......
...@@ -35,8 +35,6 @@ _kind_to_cpp_literal_suffix = { ...@@ -35,8 +35,6 @@ _kind_to_cpp_literal_suffix = {
} }
class _NameFormatter(object): class _NameFormatter(object):
"""A formatter for the names of kinds or values.""" """A formatter for the names of kinds or values."""
...@@ -268,16 +266,19 @@ class Generator(generator.Generator): ...@@ -268,16 +266,19 @@ class Generator(generator.Generator):
return used_typemaps return used_typemaps
def _GetExtraPublicHeaders(self): def _GetExtraPublicHeaders(self):
headers = set()
all_enums = list(self.module.enums) all_enums = list(self.module.enums)
for struct in self.module.structs: for struct in self.module.structs:
all_enums.extend(struct.enums) all_enums.extend(struct.enums)
for interface in self.module.interfaces: for interface in self.module.interfaces:
all_enums.extend(interface.enums) all_enums.extend(interface.enums)
if interface.uuid:
headers.add('base/token.h')
types = set(self._GetFullMojomNameForKind(typename) types = set(self._GetFullMojomNameForKind(typename)
for typename in for typename in
self.module.structs + all_enums + self.module.unions) self.module.structs + all_enums + self.module.unions)
headers = set()
for typename, typemap in self.typemap.items(): for typename, typemap in self.typemap.items():
if typename in types: if typename in types:
headers.update(typemap.get("public_headers", [])) headers.update(typemap.get("public_headers", []))
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
# method.AddParameter('baz', 0, mojom.INT32) # method.AddParameter('baz', 0, mojom.INT32)
import pickle import pickle
from uuid import UUID
class BackwardCompatibilityChecker(object): class BackwardCompatibilityChecker(object):
...@@ -286,6 +287,7 @@ ATTRIBUTE_EXTENSIBLE = 'Extensible' ...@@ -286,6 +287,7 @@ ATTRIBUTE_EXTENSIBLE = 'Extensible'
ATTRIBUTE_STABLE = 'Stable' ATTRIBUTE_STABLE = 'Stable'
ATTRIBUTE_SYNC = 'Sync' ATTRIBUTE_SYNC = 'Sync'
ATTRIBUTE_UNLIMITED_SIZE = 'UnlimitedSize' ATTRIBUTE_UNLIMITED_SIZE = 'UnlimitedSize'
ATTRIBUTE_UUID = 'Uuid'
class NamedValue(object): class NamedValue(object):
...@@ -1188,6 +1190,20 @@ class Interface(ReferenceKind): ...@@ -1188,6 +1190,20 @@ class Interface(ReferenceKind):
self.attributes) == (rhs.mojom_name, rhs.methods, rhs.enums, self.attributes) == (rhs.mojom_name, rhs.methods, rhs.enums,
rhs.constants, rhs.attributes)) 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): def __hash__(self):
return id(self) return id(self)
......
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