summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/media/router/media_router_mojo_impl.cc11
-rw-r--r--chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc1
-rw-r--r--components/arc/common/ime.mojom1
-rw-r--r--components/arc/common/net.mojom1
-rw-r--r--components/arc/common/power.mojom1
-rw-r--r--mojo/android/javatests/src/org/chromium/mojo/bindings/ValidationTest.java5
-rw-r--r--mojo/public/cpp/bindings/lib/array_internal.h22
-rw-r--r--mojo/public/cpp/bindings/lib/bindings_internal.h20
-rw-r--r--mojo/public/cpp/bindings/lib/template_util.h16
-rw-r--r--mojo/public/cpp/bindings/lib/validation_errors.cc2
-rw-r--r--mojo/public/cpp/bindings/lib/validation_errors.h4
-rw-r--r--mojo/public/cpp/bindings/lib/validation_util.h15
-rw-r--r--mojo/public/cpp/bindings/tests/union_unittest.cc38
-rw-r--r--mojo/public/cpp/bindings/tests/validation_unittest.cc55
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_good_known_enum_values.data13
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_good_known_enum_values.expected1
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_good_uknown_extensible_enum_value.data13
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_good_uknown_extensible_enum_value.expected1
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_uknown_non_extensible_enum_value.data14
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_uknown_non_extensible_enum_value.expected1
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_known_enum_array_values.data27
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_known_enum_array_values.expected1
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_uknown_extensible_enum_array_value.data20
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_uknown_extensible_enum_array_value.expected1
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_uknown_non_extensible_enum_array_value.data21
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_uknown_non_extensible_enum_array_value.expected1
-rw-r--r--mojo/public/interfaces/bindings/tests/test_unions.mojom6
-rw-r--r--mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom14
-rw-r--r--mojo/public/js/validation_unittests.js3
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl57
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl2
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl6
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl21
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl6
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl14
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl8
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl16
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl4
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl2
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/union_definition.tmpl2
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/union_serialization_definition.tmpl4
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/validation_macros.tmpl9
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl2
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_definition.tmpl7
-rw-r--r--mojo/public/tools/bindings/generators/mojom_cpp_generator.py56
-rw-r--r--mojo/public/tools/bindings/pylib/mojom/generate/module.py6
-rw-r--r--ui/arc/notification/arc_notification_item.cc4
47 files changed, 417 insertions, 138 deletions
diff --git a/chrome/browser/media/router/media_router_mojo_impl.cc b/chrome/browser/media/router/media_router_mojo_impl.cc
index bd9f6ac..f4dd491 100644
--- a/chrome/browser/media/router/media_router_mojo_impl.cc
+++ b/chrome/browser/media/router/media_router_mojo_impl.cc
@@ -730,11 +730,6 @@ void MediaRouterMojoImpl::OnRouteMessagesReceived(
void MediaRouterMojoImpl::OnSinkAvailabilityUpdated(
SinkAvailability availability) {
- if (!interfaces::MediaRouter::SinkAvailability_IsValidValue(availability)) {
- DLOG(WARNING) << "Unknown SinkAvailability value " << availability;
- return;
- }
-
if (availability_ == availability)
return;
@@ -759,12 +754,6 @@ void MediaRouterMojoImpl::OnSinkAvailabilityUpdated(
void MediaRouterMojoImpl::OnPresentationConnectionStateChanged(
const mojo::String& route_id,
interfaces::MediaRouter::PresentationConnectionState state) {
- if (!interfaces::MediaRouter::PresentationConnectionState_IsValidValue(
- state)) {
- DLOG(WARNING) << "Unknown PresentationConnectionState value " << state;
- return;
- }
-
NotifyPresentationConnectionStateChange(
route_id, mojo::PresentationConnectionStateFromMojo(state));
}
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
index ff2adb2..9cf0d44 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
@@ -407,7 +407,6 @@ void ArcAppListPrefs::OnAppIcon(const mojo::String& package,
mojo::Array<uint8_t> icon_png_data) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK_NE(0u, icon_png_data.size());
- DCHECK(arc::ScaleFactor_IsValidValue(scale_factor));
std::string app_id = GetAppId(package, activity);
if (!IsRegistered(app_id)) {
diff --git a/components/arc/common/ime.mojom b/components/arc/common/ime.mojom
index 9722ddf..e1b314e 100644
--- a/components/arc/common/ime.mojom
+++ b/components/arc/common/ime.mojom
@@ -5,6 +5,7 @@
module arc;
// Represents the type of text input field currently focused.
+[Extensible=True]
enum TextInputType {
NONE,
TEXT,
diff --git a/components/arc/common/net.mojom b/components/arc/common/net.mojom
index 0835c73..01de04e 100644
--- a/components/arc/common/net.mojom
+++ b/components/arc/common/net.mojom
@@ -4,6 +4,7 @@
module arc;
+[Extensible=True]
enum NetworkResult {
SUCCESS = 0,
FAILURE = 1,
diff --git a/components/arc/common/power.mojom b/components/arc/common/power.mojom
index b1cfbae..22792e2 100644
--- a/components/arc/common/power.mojom
+++ b/components/arc/common/power.mojom
@@ -6,6 +6,7 @@ module arc;
// Enumerates the types of wake lock the ARC instance can request from the
// host.
+[Extensible=True]
enum DisplayWakeLockType {
// Does not allow the screen to dim, turn off, or lock; prevents
// idle suspend.
diff --git a/mojo/android/javatests/src/org/chromium/mojo/bindings/ValidationTest.java b/mojo/android/javatests/src/org/chromium/mojo/bindings/ValidationTest.java
index 286566d..2989170 100644
--- a/mojo/android/javatests/src/org/chromium/mojo/bindings/ValidationTest.java
+++ b/mojo/android/javatests/src/org/chromium/mojo/bindings/ValidationTest.java
@@ -59,6 +59,11 @@ public class ValidationTest extends MojoTestCase {
if (pathname.getName().startsWith("conformance_mthd13_good_2")) {
return false;
}
+ // TODO(yzshen): skip enum validation tests because the feature is
+ // not supported in Java yet. crbug.com/581392
+ if (pathname.getName().indexOf("enum") != -1) {
+ return false;
+ }
return pathname.isFile() && pathname.getName().startsWith(mPrefix)
&& pathname.getName().endsWith(".data");
}
diff --git a/mojo/public/cpp/bindings/lib/array_internal.h b/mojo/public/cpp/bindings/lib/array_internal.h
index d351b34..1b70517 100644
--- a/mojo/public/cpp/bindings/lib/array_internal.h
+++ b/mojo/public/cpp/bindings/lib/array_internal.h
@@ -173,8 +173,30 @@ struct ArraySerializationHelper<T, false> {
<< "Primitive type should be non-nullable";
MOJO_DCHECK(!validate_params->element_validate_params)
<< "Primitive type should not have array validate params";
+
+ for (uint32_t i = 0; i < header->num_elements; ++i) {
+ if (!ValidateCaller<ElementType>::Run(elements[i]))
+ return false;
+ }
+
return true;
}
+
+ private:
+ template <typename U, bool is_enum = IsEnumDataType<U>::value>
+ struct ValidateCaller {};
+
+ template <typename U>
+ struct ValidateCaller<U, false> {
+ static bool Run(const ElementType& element) { return true; }
+ };
+
+ template <typename U>
+ struct ValidateCaller<U, true> {
+ static bool Run(const ElementType& element) {
+ return ValidateEnum(element);
+ }
+ };
};
template <>
diff --git a/mojo/public/cpp/bindings/lib/bindings_internal.h b/mojo/public/cpp/bindings/lib/bindings_internal.h
index 6d2562f..9691376 100644
--- a/mojo/public/cpp/bindings/lib/bindings_internal.h
+++ b/mojo/public/cpp/bindings/lib/bindings_internal.h
@@ -94,12 +94,32 @@ struct IsHandle {
template <typename T>
struct IsUnionDataType {
+ private:
template <typename U>
static YesType Test(const typename U::MojomUnionDataType*);
template <typename U>
static NoType Test(...);
+ EnsureTypeIsComplete<T> check_t_;
+
+ public:
+ static const bool value =
+ sizeof(Test<T>(0)) == sizeof(YesType) && !IsConst<T>::value;
+};
+
+template <typename T>
+struct IsEnumDataType {
+ private:
+ template <typename U>
+ static YesType Test(const typename U::MojomEnumDataType*);
+
+ template <typename U>
+ static NoType Test(...);
+
+ EnsureTypeIsComplete<T> check_t_;
+
+ public:
static const bool value =
sizeof(Test<T>(0)) == sizeof(YesType) && !IsConst<T>::value;
};
diff --git a/mojo/public/cpp/bindings/lib/template_util.h b/mojo/public/cpp/bindings/lib/template_util.h
index ceaf8e0..68390c1 100644
--- a/mojo/public/cpp/bindings/lib/template_util.h
+++ b/mojo/public/cpp/bindings/lib/template_util.h
@@ -70,18 +70,24 @@ template <typename A>
struct IsSame<A, A> {
static bool const value = true;
};
+
+template <typename T>
+struct EnsureTypeIsComplete {
+ // sizeof() cannot be applied to incomplete types, this line will fail
+ // compilation if T is forward declaration.
+ using CheckSize = char (*)[sizeof(T)];
+};
+
template <typename Base, typename Derived>
struct IsBaseOf {
private:
- // This class doesn't work correctly with forward declarations.
- // Because sizeof cannot be applied to incomplete types, this line prevents us
- // from passing in forward declarations.
- typedef char (*EnsureTypesAreComplete)[sizeof(Base) + sizeof(Derived)];
-
static Derived* CreateDerived();
static char(&Check(Base*))[1];
static char(&Check(...))[2];
+ EnsureTypeIsComplete<Base> check_base_;
+ EnsureTypeIsComplete<Derived> check_derived_;
+
public:
static bool const value = sizeof Check(CreateDerived()) == 1 &&
!IsSame<Base const, void const>::value;
diff --git a/mojo/public/cpp/bindings/lib/validation_errors.cc b/mojo/public/cpp/bindings/lib/validation_errors.cc
index 4db8455..c57bbc2 100644
--- a/mojo/public/cpp/bindings/lib/validation_errors.cc
+++ b/mojo/public/cpp/bindings/lib/validation_errors.cc
@@ -50,6 +50,8 @@ const char* ValidationErrorToString(ValidationError error) {
return "VALIDATION_ERROR_DIFFERENT_SIZED_ARRAYS_IN_MAP";
case VALIDATION_ERROR_UNKNOWN_UNION_TAG:
return "VALIDATION_ERROR_UNKNOWN_UNION_TAG";
+ case VALIDATION_ERROR_UNKNOWN_ENUM_VALUE:
+ return "VALIDATION_ERROR_UNKNOWN_ENUM_VALUE";
}
return "Unknown error";
diff --git a/mojo/public/cpp/bindings/lib/validation_errors.h b/mojo/public/cpp/bindings/lib/validation_errors.h
index 80a66fb..fab16c1 100644
--- a/mojo/public/cpp/bindings/lib/validation_errors.h
+++ b/mojo/public/cpp/bindings/lib/validation_errors.h
@@ -59,7 +59,9 @@ enum ValidationError {
// lengths.
VALIDATION_ERROR_DIFFERENT_SIZED_ARRAYS_IN_MAP,
// Attempted to deserialize a tagged union with an unknown tag.
- VALIDATION_ERROR_UNKNOWN_UNION_TAG
+ VALIDATION_ERROR_UNKNOWN_UNION_TAG,
+ // A value of a non-extensible enum type is unknown.
+ VALIDATION_ERROR_UNKNOWN_ENUM_VALUE
};
const char* ValidationErrorToString(ValidationError error);
diff --git a/mojo/public/cpp/bindings/lib/validation_util.h b/mojo/public/cpp/bindings/lib/validation_util.h
index 41049c0..5314a36 100644
--- a/mojo/public/cpp/bindings/lib/validation_util.h
+++ b/mojo/public/cpp/bindings/lib/validation_util.h
@@ -124,6 +124,21 @@ bool ValidateHandle(const Handle& input, BoundsChecker* bounds_checker);
bool ValidateAssociatedInterfaceId(InterfaceId input);
+// Checks whether the given enum value is valid. Please note that any value is
+// valid for an extensible enum, although it may be from a newer version and
+// thus unknown.
+template <typename T>
+bool ValidateEnum(const T& input) {
+ if (T::kIsExtensible)
+ return true;
+
+ if (T::IsKnownValue(input.value))
+ return true;
+
+ ReportValidationError(VALIDATION_ERROR_UNKNOWN_ENUM_VALUE);
+ return false;
+}
+
} // namespace internal
} // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/union_unittest.cc b/mojo/public/cpp/bindings/tests/union_unittest.cc
index 60bde4b..c90069b 100644
--- a/mojo/public/cpp/bindings/tests/union_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/union_unittest.cc
@@ -264,6 +264,44 @@ TEST(UnionTest, UnknownTagValidation) {
free(raw_buf);
}
+TEST(UnionTest, UnknownEnumValueValidation) {
+ PodUnionPtr pod(PodUnion::New());
+ pod->set_f_enum(static_cast<AnEnum>(0xFFFF));
+
+ size_t size = GetSerializedSize_(pod, false);
+ EXPECT_EQ(16U, size);
+
+ mojo::internal::FixedBufferForTesting buf(size);
+ internal::PodUnion_Data* data = nullptr;
+ SerializeUnion_(std::move(pod), &buf, &data, false);
+
+ void* raw_buf = buf.Leak();
+ mojo::internal::BoundsChecker bounds_checker(data,
+ static_cast<uint32_t>(size), 0);
+ EXPECT_FALSE(
+ internal::PodUnion_Data::Validate(raw_buf, &bounds_checker, false));
+ free(raw_buf);
+}
+
+TEST(UnionTest, UnknownExtensibleEnumValueValidation) {
+ PodUnionPtr pod(PodUnion::New());
+ pod->set_f_extensible_enum(static_cast<AnExtensibleEnum>(0xFFFF));
+
+ size_t size = GetSerializedSize_(pod, false);
+ EXPECT_EQ(16U, size);
+
+ mojo::internal::FixedBufferForTesting buf(size);
+ internal::PodUnion_Data* data = nullptr;
+ SerializeUnion_(std::move(pod), &buf, &data, false);
+
+ void* raw_buf = buf.Leak();
+ mojo::internal::BoundsChecker bounds_checker(data,
+ static_cast<uint32_t>(size), 0);
+ EXPECT_TRUE(
+ internal::PodUnion_Data::Validate(raw_buf, &bounds_checker, false));
+ free(raw_buf);
+}
+
TEST(UnionTest, StringGetterSetter) {
ObjectUnionPtr pod(ObjectUnion::New());
diff --git a/mojo/public/cpp/bindings/tests/validation_unittest.cc b/mojo/public/cpp/bindings/tests/validation_unittest.cc
index bb1c745..252a31a 100644
--- a/mojo/public/cpp/bindings/tests/validation_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/validation_unittest.cc
@@ -194,13 +194,17 @@ class DummyMessageReceiver : public MessageReceiver {
}
};
-using ValidationTest = testing::Test;
+class ValidationTest : public testing::Test {
+ public:
+ ValidationTest() : loop_(common::MessagePumpMojo::Create()) {}
+
+ protected:
+ base::MessageLoop loop_;
+};
class ValidationIntegrationTest : public ValidationTest {
public:
- ValidationIntegrationTest()
- : loop_(common::MessagePumpMojo::Create()),
- test_message_receiver_(nullptr) {}
+ ValidationIntegrationTest() : test_message_receiver_(nullptr) {}
~ValidationIntegrationTest() override {}
@@ -250,7 +254,6 @@ class ValidationIntegrationTest : public ValidationTest {
void PumpMessages() { loop_.RunUntilIdle(); }
- base::MessageLoop loop_;
TestMessageReceiver* test_message_receiver_;
ScopedMessagePipeHandle testee_endpoint_;
};
@@ -462,37 +465,31 @@ TEST_F(ValidationTest, ValidateEncodedPointer) {
EXPECT_FALSE(mojo::internal::ValidateEncodedPointer(&offset));
}
-// Tests the IsValidValue() function generated for BasicEnum.
+// Tests the IsKnownEnumValue() function generated for BasicEnum.
TEST(EnumValueValidationTest, BasicEnum) {
// BasicEnum can have -3,0,1,10 as possible integral values.
- EXPECT_FALSE(BasicEnum_IsValidValue(static_cast<BasicEnum>(-4)));
- EXPECT_TRUE(BasicEnum_IsValidValue(static_cast<BasicEnum>(-3)));
- EXPECT_FALSE(BasicEnum_IsValidValue(static_cast<BasicEnum>(-2)));
- EXPECT_FALSE(BasicEnum_IsValidValue(static_cast<BasicEnum>(-1)));
- EXPECT_TRUE(BasicEnum_IsValidValue(static_cast<BasicEnum>(0)));
- EXPECT_TRUE(BasicEnum_IsValidValue(static_cast<BasicEnum>(1)));
- EXPECT_FALSE(BasicEnum_IsValidValue(static_cast<BasicEnum>(2)));
- EXPECT_FALSE(BasicEnum_IsValidValue(static_cast<BasicEnum>(9)));
+ EXPECT_FALSE(IsKnownEnumValue(static_cast<BasicEnum>(-4)));
+ EXPECT_TRUE(IsKnownEnumValue(static_cast<BasicEnum>(-3)));
+ EXPECT_FALSE(IsKnownEnumValue(static_cast<BasicEnum>(-2)));
+ EXPECT_FALSE(IsKnownEnumValue(static_cast<BasicEnum>(-1)));
+ EXPECT_TRUE(IsKnownEnumValue(static_cast<BasicEnum>(0)));
+ EXPECT_TRUE(IsKnownEnumValue(static_cast<BasicEnum>(1)));
+ EXPECT_FALSE(IsKnownEnumValue(static_cast<BasicEnum>(2)));
+ EXPECT_FALSE(IsKnownEnumValue(static_cast<BasicEnum>(9)));
// In the mojom, we represent this value as hex (0xa).
- EXPECT_TRUE(BasicEnum_IsValidValue(static_cast<BasicEnum>(10)));
- EXPECT_FALSE(BasicEnum_IsValidValue(static_cast<BasicEnum>(11)));
+ EXPECT_TRUE(IsKnownEnumValue(static_cast<BasicEnum>(10)));
+ EXPECT_FALSE(IsKnownEnumValue(static_cast<BasicEnum>(11)));
}
-// Tests the IsValidValue() method generated for StructWithEnum.
+// Tests the IsKnownEnumValue() method generated for StructWithEnum.
TEST(EnumValueValidationTest, EnumWithin) {
// StructWithEnum::EnumWithin can have [0,4] as possible integral values.
- EXPECT_FALSE(StructWithEnum::EnumWithin_IsValidValue(
- static_cast<StructWithEnum::EnumWithin>(-1)));
- EXPECT_TRUE(StructWithEnum::EnumWithin_IsValidValue(
- static_cast<StructWithEnum::EnumWithin>(0)));
- EXPECT_TRUE(StructWithEnum::EnumWithin_IsValidValue(
- static_cast<StructWithEnum::EnumWithin>(1)));
- EXPECT_TRUE(StructWithEnum::EnumWithin_IsValidValue(
- static_cast<StructWithEnum::EnumWithin>(2)));
- EXPECT_TRUE(StructWithEnum::EnumWithin_IsValidValue(
- static_cast<StructWithEnum::EnumWithin>(3)));
- EXPECT_FALSE(StructWithEnum::EnumWithin_IsValidValue(
- static_cast<StructWithEnum::EnumWithin>(4)));
+ EXPECT_FALSE(IsKnownEnumValue(static_cast<StructWithEnum::EnumWithin>(-1)));
+ EXPECT_TRUE(IsKnownEnumValue(static_cast<StructWithEnum::EnumWithin>(0)));
+ EXPECT_TRUE(IsKnownEnumValue(static_cast<StructWithEnum::EnumWithin>(1)));
+ EXPECT_TRUE(IsKnownEnumValue(static_cast<StructWithEnum::EnumWithin>(2)));
+ EXPECT_TRUE(IsKnownEnumValue(static_cast<StructWithEnum::EnumWithin>(3)));
+ EXPECT_FALSE(IsKnownEnumValue(static_cast<StructWithEnum::EnumWithin>(4)));
}
} // namespace
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_good_known_enum_values.data b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_good_known_enum_values.data
new file mode 100644
index 0000000..1444849
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_good_known_enum_values.data
@@ -0,0 +1,13 @@
+[dist4]message_header // num_bytes
+[u4]0 // version
+[u4]0 // interface ID
+[u4]14 // name
+[u4]0 // flags
+[u4]0 // padding
+[anchr]message_header
+
+[dist4]method14_params // num_bytes
+[u4]0 // version
+[u4]0 // param0
+[u4]1 // param1
+[anchr]method14_params
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_good_known_enum_values.expected b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_good_known_enum_values.expected
new file mode 100644
index 0000000..7ef22e9
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_good_known_enum_values.expected
@@ -0,0 +1 @@
+PASS
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_good_uknown_extensible_enum_value.data b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_good_uknown_extensible_enum_value.data
new file mode 100644
index 0000000..50b9ea3
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_good_uknown_extensible_enum_value.data
@@ -0,0 +1,13 @@
+[dist4]message_header // num_bytes
+[u4]0 // version
+[u4]0 // interface ID
+[u4]14 // name
+[u4]0 // flags
+[u4]0 // padding
+[anchr]message_header
+
+[dist4]method14_params // num_bytes
+[u4]0 // version
+[u4]0 // param0
+[u4]0xFFFFFFFF // param1: Unknown value is okay for extensible enum.
+[anchr]method14_params
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_good_uknown_extensible_enum_value.expected b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_good_uknown_extensible_enum_value.expected
new file mode 100644
index 0000000..7ef22e9
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_good_uknown_extensible_enum_value.expected
@@ -0,0 +1 @@
+PASS
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_uknown_non_extensible_enum_value.data b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_uknown_non_extensible_enum_value.data
new file mode 100644
index 0000000..567f23b
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_uknown_non_extensible_enum_value.data
@@ -0,0 +1,14 @@
+[dist4]message_header // num_bytes
+[u4]0 // version
+[u4]0 // interface ID
+[u4]14 // name
+[u4]0 // flags
+[u4]0 // padding
+[anchr]message_header
+
+[dist4]method14_params // num_bytes
+[u4]0 // version
+[u4]0xFFFFFFFF // param0: Unknown value is not allowed for
+ // non-extensible enum.
+[u4]2 // param1
+[anchr]method14_params
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_uknown_non_extensible_enum_value.expected b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_uknown_non_extensible_enum_value.expected
new file mode 100644
index 0000000..9ef4ce3
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd14_uknown_non_extensible_enum_value.expected
@@ -0,0 +1 @@
+VALIDATION_ERROR_UNKNOWN_ENUM_VALUE
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_known_enum_array_values.data b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_known_enum_array_values.data
new file mode 100644
index 0000000..c418d89
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_known_enum_array_values.data
@@ -0,0 +1,27 @@
+[dist4]message_header // num_bytes
+[u4]0 // version
+[u4]0 // interface ID
+[u4]15 // name
+[u4]0 // flags
+[u4]0 // padding
+[anchr]message_header
+
+[dist4]method15_params // num_bytes
+[u4]0 // version
+[dist8]enum_array_0 // param0
+[dist8]enum_array_1 // param1
+[anchr]method15_params
+
+[anchr]enum_array_0
+[dist4]enum_array_0_member // num_bytes
+[u4]2 // num_elements
+[u4]0
+[u4]1
+[anchr]enum_array_0_member
+
+[anchr]enum_array_1
+[dist4]enum_array_1_member // num_bytes
+[u4]2 // num_elements
+[u4]0
+[u4]1
+[anchr]enum_array_1_member
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_known_enum_array_values.expected b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_known_enum_array_values.expected
new file mode 100644
index 0000000..7ef22e9
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_known_enum_array_values.expected
@@ -0,0 +1 @@
+PASS
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_uknown_extensible_enum_array_value.data b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_uknown_extensible_enum_array_value.data
new file mode 100644
index 0000000..b6be6d9
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_uknown_extensible_enum_array_value.data
@@ -0,0 +1,20 @@
+[dist4]message_header // num_bytes
+[u4]0 // version
+[u4]0 // interface ID
+[u4]15 // name
+[u4]0 // flags
+[u4]0 // padding
+[anchr]message_header
+
+[dist4]method15_params // num_bytes
+[u4]0 // version
+[u8]0 // param0
+[dist8]enum_array_1 // param1
+[anchr]method15_params
+
+[anchr]enum_array_1
+[dist4]enum_array_1_member // num_bytes
+[u4]2 // num_elements
+[u4]0
+[u4]0x1234 // Unknown value is okay for extensible enum.
+[anchr]enum_array_1_member
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_uknown_extensible_enum_array_value.expected b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_uknown_extensible_enum_array_value.expected
new file mode 100644
index 0000000..7ef22e9
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_uknown_extensible_enum_array_value.expected
@@ -0,0 +1 @@
+PASS
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_uknown_non_extensible_enum_array_value.data b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_uknown_non_extensible_enum_array_value.data
new file mode 100644
index 0000000..1cd3484
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_uknown_non_extensible_enum_array_value.data
@@ -0,0 +1,21 @@
+[dist4]message_header // num_bytes
+[u4]0 // version
+[u4]0 // interface ID
+[u4]15 // name
+[u4]0 // flags
+[u4]0 // padding
+[anchr]message_header
+
+[dist4]method15_params // num_bytes
+[u4]0 // version
+[dist8]enum_array_0 // param0
+[u8]0 // param1
+[anchr]method15_params
+
+[anchr]enum_array_0
+[dist4]enum_array_0_member // num_bytes
+[u4]2 // num_elements
+[u4]0x5678 // Unknown value is not allowed for non-extensible
+ // enum.
+[u4]1
+[anchr]enum_array_0_member
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_uknown_non_extensible_enum_array_value.expected b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_uknown_non_extensible_enum_array_value.expected
new file mode 100644
index 0000000..9ef4ce3
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_uknown_non_extensible_enum_array_value.expected
@@ -0,0 +1 @@
+VALIDATION_ERROR_UNKNOWN_ENUM_VALUE
diff --git a/mojo/public/interfaces/bindings/tests/test_unions.mojom b/mojo/public/interfaces/bindings/tests/test_unions.mojom
index e998f47..16a291a 100644
--- a/mojo/public/interfaces/bindings/tests/test_unions.mojom
+++ b/mojo/public/interfaces/bindings/tests/test_unions.mojom
@@ -8,6 +8,11 @@ enum AnEnum {
FIRST, SECOND
};
+[Extensible=True]
+enum AnExtensibleEnum {
+ FIRST, SECOND, THIRD
+};
+
union PodUnion {
int8 f_int8;
int8 f_int8_other;
@@ -22,6 +27,7 @@ union PodUnion {
double f_double;
bool f_bool;
AnEnum f_enum;
+ AnExtensibleEnum f_extensible_enum;
};
union ObjectUnion {
diff --git a/mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom b/mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom
index dd2eb4c..2eee610 100644
--- a/mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom
+++ b/mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom
@@ -44,6 +44,18 @@ struct StructG {
interface InterfaceA {
};
+enum EnumA {
+ ENUM_A_0,
+ ENUM_A_1
+};
+
+[Extensible=True]
+enum EnumB {
+ ENUM_B_0,
+ ENUM_B_1,
+ ENUM_B_2
+};
+
// This interface is used for testing bounds-checking in the mojom
// binding code. If you add a method please update the files
// ./data/validation/boundscheck_*. If you add a response please update
@@ -68,6 +80,8 @@ interface ConformanceTestInterface {
Method11(StructG param0);
Method12(float param0) => (float param0);
Method13(InterfaceA? param0, uint32 param1, InterfaceA? param2);
+ Method14(EnumA param0, EnumB param1);
+ Method15(array<EnumA>? param0, array<EnumB>? param1);
};
struct BasicStruct {
diff --git a/mojo/public/js/validation_unittests.js b/mojo/public/js/validation_unittests.js
index ca43a65..4cc17f9 100644
--- a/mojo/public/js/validation_unittests.js
+++ b/mojo/public/js/validation_unittests.js
@@ -227,12 +227,15 @@ define([
// because JS numbers are limited to 53 bits.
// TODO(yzshen) Skipping struct versioning tests (tests with "mthd11"
// in the name) because the feature is not supported in JS yet.
+ // TODO(yzshen) Skipping enum validation tests (tests with "enum" in the
+ // name) because the feature is not supported in JS yet. crbug.com/581390
// TODO(rudominer): Temporarily skipping 'no-such-method',
// 'invalid_request_flags', and 'invalid_response_flags' until additional
// logic in *RequestValidator and *ResponseValidator is ported from
// cpp to js.
if (testFiles[i].indexOf("overflow") != -1 ||
testFiles[i].indexOf("mthd11") != -1 ||
+ testFiles[i].indexOf("enum") != -1 ||
testFiles[i].indexOf("no_such_method") != -1 ||
testFiles[i].indexOf("invalid_request_flags") != -1 ||
testFiles[i].indexOf("invalid_response_flags") != -1) {
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl
index d11b198..745ebf6 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl
@@ -1,9 +1,7 @@
{#---
Macro for enum definition, and the declaration of associated functions.
- `is_static` is relevant if this enum declaration is defined within a class, in
- which case associated functions need to be static.
---#}
-{%- macro enum_decl(enum, is_static=false) %}
+{%- macro enum_decl(enum) %}
enum class {{enum.name}} : int32_t {
{%- for field in enum.fields %}
{%- if field.value %}
@@ -13,20 +11,36 @@ enum class {{enum.name}} : int32_t {
{%- endif %}
{%- endfor %}
};
-{{is_valid_enum_decl(enum, is_static)}}
{%- endmacro %}
-{#--- macros for the declaration & definitions of enum-associated functions.
- Namely:
- * {enum_name}_IsValidValue: returns true if the given enum has a valid value
- for this generated version of enum.
----#}
+{%- macro enum_data_decl(enum) %}
+struct {{enum.name}}_Data {
+ public:
+ // Used to identify Mojom Enum Data Classes.
+ typedef void MojomEnumDataType;
+
+ static bool const kIsExtensible = {% if enum.extensible %}true{% else %}false{% endif %};
+
+ static bool IsKnownValue(int32_t value) {
+ switch (value) {
+{%- for enum_field in enum.fields|groupby('numeric_value') %}
+ case {{enum_field[0]}}:
+{%- endfor %}
+ return true;
+ }
+ return false;
+ }
-{%- macro is_valid_enum_decl(enum, is_static=false) %}
-{% if is_static %}static {% endif -%}
-bool {{enum.name}}_IsValidValue({{enum.name}} value);
+ int32_t value;
+};
{%- endmacro %}
+{#--- macros for enum-associated functions. Namely:
+ * operator<<(): outputs the given enum value.
+ * IsKnownEnumValue(): returns true if the given enum value exists in this
+ generated version of enum.
+---#}
+
{%- macro enum_stream_operator(enum) %}
inline std::ostream& operator<<(std::ostream& os, {{enum|get_name_for_kind}} value) {
switch(value) {
@@ -48,20 +62,9 @@ inline std::ostream& operator<<(std::ostream& os, {{enum|get_name_for_kind}} val
}
{%- endmacro %}
-{%- macro is_valid_enum_def(enum, class_name = '') %}
-{% if class_name != '' -%}
-// static
-bool {{class_name}}::
-{%- else -%}
-{{"bool "}}
-{%- endif -%}
-{{enum.name}}_IsValidValue({{enum.name}} value) {
- switch (static_cast<int32_t>(value)) {
-{%- for enum_field in enum.fields|groupby('numeric_value') %}
- case {{enum_field[0]}}:
-{%- endfor %}
- return true;
- }
- return false;
+{%- macro is_known_enum_value(enum) %}
+inline bool IsKnownEnumValue({{enum|get_name_for_kind}} value) {
+ return {{enum|get_qualified_name_for_kind(internal=True)}}::IsKnownValue(
+ static_cast<int32_t>(value));
}
{%- endmacro %}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl
index 2115a86..7b4bab2 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl
@@ -28,7 +28,7 @@ class {{interface.name}} {
{#--- Enums #}
{% from "enum_macros.tmpl" import enum_decl -%}
{%- for enum in interface.enums %}
- {{enum_decl(enum, is_static=true)|indent(2)}}
+ {{enum_decl(enum)|indent(2)}}
{%- endfor %}
{#--- Constants #}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
index df2ee80a..0b49e9a 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
@@ -1,6 +1,5 @@
{%- import "interface_macros.tmpl" as interface_macros %}
{%- import "struct_macros.tmpl" as struct_macros %}
-{%- from "enum_macros.tmpl" import is_valid_enum_def %}
{%- set class_name = interface.name %}
{%- set proxy_name = interface.name ~ "Proxy" %}
@@ -45,11 +44,6 @@ MOJO_STATIC_CONST_MEMBER_DEFINITION const {{constant.kind|cpp_pod_type}} {{inter
{%- endif %}
{%- endfor %}
-{#--- Enums #}
-{%- for enum in interface.enums %}
- {{is_valid_enum_def(enum, class_name=interface.name)|indent(2)}}
-{%- endfor %}
-
{#--- ForwardToCallback definition #}
{%- for method in interface.methods -%}
{%- if method.response_parameters != None %}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl
index c59c9f7..c761c25 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl
@@ -63,6 +63,12 @@ class {{struct.name}}_Data;
class {{union.name}}_Data;
{%- endfor %}
+{#--- Enums #}
+{% from "enum_macros.tmpl" import enum_data_decl -%}
+{%- for enum in enums %}
+ {{enum_data_decl(enum)}}
+{%- endfor %}
+
#pragma pack(push, 1)
{#--- Unions must be declared first because they can be members of structs #}
@@ -71,11 +77,24 @@ class {{union.name}}_Data;
{% include "union_declaration.tmpl" %}
{%- endfor %}
-{#--- Class declarations #}
+{#--- Struct class declarations #}
{% for struct in structs %}
{% include "struct_declaration.tmpl" %}
{%- endfor %}
+{#--- Interface class declarations. They are needed only when they contain
+ enums. #}
+{%- for interface in interfaces %}
+{%- if interface.enums %}
+class {{interface.name}}_Data {
+ public:
+{%- for enum in interface.enums %}
+ {{enum_data_decl(enum)|indent(2)}}
+{%- endfor %}
+};
+{%- endif %}
+{%- endfor %}
+
#pragma pack(pop)
} // namespace internal
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
index ae217e8..b8f5b7d 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
@@ -91,12 +91,6 @@ const uint32_t {{method_name}} = {{method.ordinal}};
} // namespace internal
-{#--- Enums #}
-{%- from "enum_macros.tmpl" import is_valid_enum_def -%}
-{%- for enum in enums -%}
- {{is_valid_enum_def(enum, class_name='')}}
-{%- endfor %}
-
{#--- Struct Constants #}
{%- for struct in structs %}
{%- for constant in struct.constants %}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
index 5ef35a2..2314f6e 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
@@ -51,9 +51,11 @@ namespace {{variant}} {
{#--- Enums #}
{% from "enum_macros.tmpl" import enum_decl -%}
{% from "enum_macros.tmpl" import enum_stream_operator -%}
-{% for enum in enums %}
+{% from "enum_macros.tmpl" import is_known_enum_value -%}
+{%- for enum in enums %}
{{enum_decl(enum)}}
{{enum_stream_operator(enum)}}
+ {{is_known_enum_value(enum)}}
{%- endfor %}
{#--- Constants #}
@@ -161,15 +163,17 @@ typedef mojo::StructPtr<{{union.name}}> {{union.name}}Ptr;
{%- endfor %}
{%- endif %}
-{% for struct in structs %}
-{% for enum in struct.enums %}
+{%- for struct in structs %}
+{%- for enum in struct.enums %}
{{enum_stream_operator(enum)}}
+{{is_known_enum_value(enum)}}
{%- endfor %}
{%- endfor %}
-{% for interface in interfaces %}
-{% for enum in interface.enums %}
+{%- for interface in interfaces %}
+{%- for enum in interface.enums %}
{{enum_stream_operator(enum)}}
+{{is_known_enum_value(enum)}}
{%- endfor %}
{%- endfor %}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl
index 255005a..8b3c4ce 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl
@@ -10,14 +10,18 @@ class {{class_name}} {
void EncodePointersAndHandles(std::vector<mojo::Handle>* handles);
void DecodePointersAndHandles(std::vector<mojo::Handle>* handles);
+{% from "enum_macros.tmpl" import enum_data_decl -%}
+{#--- Enums #}
+{%- for enum in struct.enums -%}
+ {{enum_data_decl(enum)|indent(2)}}
+{%- endfor %}
+
mojo::internal::StructHeader header_;
{%- for packed_field in struct.packed.packed_fields %}
{%- set name = packed_field.field.name %}
{%- set kind = packed_field.field.kind %}
{%- if kind.spec == 'b' %}
uint8_t {{name}} : 1;
-{%- elif kind|is_enum_kind %}
- int32_t {{name}};
{%- else %}
{{kind|cpp_field_type}} {{name}};
{%- endif %}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl
index 6a82549..ecb6480 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl
@@ -91,6 +91,15 @@
return false;
{%- endmacro %}
+{#- Validates the specified struct field, which is supposed to be an enum.
+ This macro is expanded by the Validate() method. #}
+{%- macro _validate_enum(struct, packed_field) %}
+{%- set name = packed_field.field.name %}
+{%- set kind = packed_field.field.kind %}
+ if (!mojo::internal::ValidateEnum(object->{{name}}))
+ return false;
+{%- endmacro %}
+
// static
{{class_name}}* {{class_name}}::New(mojo::internal::Buffer* buf) {
return new (buf->Allocate(sizeof({{class_name}}))) {{class_name}}();
@@ -146,7 +155,8 @@ bool {{class_name}}::Validate(const void* data,
{%- for packed_field in struct.packed.packed_fields_in_ordinal_order %}
{%- set kind = packed_field.field.kind %}
{%- if kind|is_object_kind or kind|is_any_handle_kind or
- kind|is_interface_kind or kind|is_associated_kind %}
+ kind|is_interface_kind or kind|is_associated_kind or
+ kind|is_enum_kind %}
{%- if packed_field.min_version > last_checked_version %}
{%- set last_checked_version = packed_field.min_version %}
if (object->header_.version < {{packed_field.min_version}})
@@ -156,8 +166,10 @@ bool {{class_name}}::Validate(const void* data,
{{_validate_object(struct, packed_field)}}
{%- elif kind|is_any_handle_kind or kind|is_interface_kind %}
{{_validate_handle(struct, packed_field)}}
-{%- else %}
+{%- elif kind|is_associated_kind %}
{{_validate_associated(struct, packed_field)}}
+{%- else %}
+{{_validate_enum(struct, packed_field)}}
{%- endif %}
{%- endif %}
{%- endfor %}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl
index ebc6048..5405fa4 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl
@@ -111,7 +111,7 @@
{{output}}->{{name}} = mojo::internal::AssociatedInterfaceRequestHelper::PassHandle(&{{input_field}}).release();
{%- endif %}
{%- elif kind|is_enum_kind %}
- {{output}}->{{name}} = static_cast<int32_t>({{input_field}});
+ {{output}}->{{name}}.value = static_cast<int32_t>({{input_field}});
{%- else %}
{{output}}->{{name}} = {{input_field}};
{%- endif %}
@@ -181,7 +181,7 @@
&{{output_field}},
({{context}})->router->CreateLocalEndpointHandle(mojo::internal::FetchAndReset(&{{input}}->{{name}})));
{%- elif kind|is_enum_kind %}
- {{output_field}} = static_cast<{{kind|cpp_wrapper_type}}>({{input}}->{{name}});
+ {{output_field}} = static_cast<{{kind|cpp_wrapper_type}}>({{input}}->{{name}}.value);
{%- else %}
{{output_field}} = {{input}}->{{name}};
{%- endif %}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl
index 52aafac..1fd9cf3 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl
@@ -33,7 +33,7 @@ class {{struct.name}}_Reader {
// TODO(rockot): Support reading associated kinds. ({{name}}() omitted)
{%- elif kind|is_enum_kind %}
{{kind|cpp_result_type}} {{name}}() const {
- return static_cast<{{kind|cpp_result_type}}>(data_->{{name}});
+ return static_cast<{{kind|cpp_result_type}}>(data_->{{name}}.value);
}
{%- else %}
{{kind|cpp_result_type}} {{name}}() const { return data_->{{name}}; }
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/union_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/union_definition.tmpl
index 087499a..9e39e35 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/union_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/union_definition.tmpl
@@ -34,7 +34,7 @@ bool {{class_name}}::Validate(const void* data,
switch (object->tag) {
{% for field in union.fields %}
case {{enum_name}}::{{field.name|upper}}: {
-{{ validation_macros.validate_union_field(field, union)|indent(8) }}
+ {{ validation_macros.validate_union_field(field, union)|indent(6) }}
}
{%- endfor %}
default: {
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_definition.tmpl
index f067e64..6fde8c9 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_definition.tmpl
@@ -79,7 +79,7 @@ void SerializeUnion_({{union.name}}Ptr input, mojo::internal::Buffer* buf,
{%- elif field.kind|is_associated_kind %}
// TODO(yzshen): add seralization logic for associated kinds.
{% elif field.kind|is_enum_kind %}
- result->data.f_{{field.name}} = static_cast<int32_t>(input_acc.data()->{{field.name}});
+ result->data.f_{{field.name}}.value = static_cast<int32_t>(input_acc.data()->{{field.name}});
{% else %}
result->data.f_{{field.name}} = input_acc.data()->{{field.name}};
{%- endif %}
@@ -124,7 +124,7 @@ bool Deserialize_(internal::{{union.name}}_Data* input,
{%- elif field.kind|is_associated_kind %}
// TODO(yzshen): add deserialization logic for associated kinds.
{% elif field.kind|is_enum_kind %}
- result->set_{{field.name}}(static_cast<{{field.kind|cpp_wrapper_type}}>(input->data.f_{{field.name}}));
+ result->set_{{field.name}}(static_cast<{{field.kind|cpp_wrapper_type}}>(input->data.f_{{field.name}}.value));
{% else %}
result->set_{{field.name}}(input->data.f_{{field.name}});
{%- endif %}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/validation_macros.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/validation_macros.tmpl
index 5cb1dc8..99731fb 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/validation_macros.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/validation_macros.tmpl
@@ -41,6 +41,11 @@ if (!{{field.kind|cpp_wrapper_type}}::Data_::Validate(
}
{%- endmacro -%}
+{%- macro validate_enum(field_expr, field) -%}
+if (!mojo::internal::ValidateEnum(*{{field_expr}}))
+ return false;
+{%- endmacro -%}
+
{%- macro validate_union_field(field, union) %}
{%- set field_expr = "(reinterpret_cast<const "
~ field.kind|cpp_union_field_type
@@ -61,5 +66,9 @@ if (!{{field.kind|cpp_wrapper_type}}::Data_::Validate(
{%- if field.kind|is_any_handle_kind -%}
{{ validate_handle(field_expr, field, union.name) }}
{%- endif %}
+
+{%- if field.kind|is_enum_kind -%}
+{{ validate_enum(field_expr, field) }}
+{%- endif %}
return true;
{%- endmacro %}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl
index 7861942..d0b9fd9 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl
@@ -9,7 +9,7 @@ class {{struct.name}} {
{#--- Enums #}
{%- for enum in struct.enums -%}
- {{enum_decl(enum, is_static=true)|indent(2)}}
+ {{enum_decl(enum)|indent(2)}}
{%- endfor %}
{#--- Constants #}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_definition.tmpl
index a68154f..133ac6f 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_definition.tmpl
@@ -1,10 +1,3 @@
-{%- from "enum_macros.tmpl" import is_valid_enum_def %}
-
-{#--- Enums #}
-{%- for enum in struct.enums -%}
- {{is_valid_enum_def(enum, class_name=struct.name)}}
-{%- endfor %}
-
// static
{{struct.name}}Ptr {{struct.name}}::New() {
{{struct.name}}Ptr rv;
diff --git a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
index eb2f03b..e328867 100644
--- a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
+++ b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
@@ -61,24 +61,39 @@ def DefaultValue(field):
def NamespaceToArray(namespace):
return namespace.split(".") if namespace else []
-def GetNameForKind(kind, internal = False):
+def GetNamePartsForKind(kind, add_same_module_namespaces, internal):
+ def MapKindName_(kind):
+ if not internal:
+ return kind.name
+ if (mojom.IsStructKind(kind) or mojom.IsUnionKind(kind) or
+ mojom.IsInterfaceKind(kind) or mojom.IsEnumKind(kind)):
+ return kind.name + "_Data"
+ return kind.name
+
parts = []
if kind.imported_from:
parts.extend(NamespaceToArray(kind.imported_from["namespace"]))
+ elif hasattr(kind, "module") and add_same_module_namespaces:
+ parts.extend(NamespaceToArray(kind.module.namespace))
if internal:
parts.append("internal")
if kind.parent_kind:
- parts.append(kind.parent_kind.name)
- parts.append(kind.name)
+ parts.append(MapKindName_(kind.parent_kind))
+ parts.append(MapKindName_(kind))
+ return parts
+
+def GetNameForKind(kind, internal=False):
+ parts = GetNamePartsForKind(kind, False, internal)
+ return "::".join(parts)
+
+def GetQualifiedNameForKind(kind, internal=False):
+ # Always start with an empty part to force a leading "::" on output.
+ parts = [""]
+ parts.extend(GetNamePartsForKind(kind, True, internal))
return "::".join(parts)
def GetFullMojomNameForKind(kind):
- parts = []
- if kind.imported_from:
- parts.extend(NamespaceToArray(kind.imported_from["namespace"]))
- elif hasattr(kind, "module"):
- parts.extend(NamespaceToArray(kind.module.namespace))
- parts.append(kind.name)
+ parts = GetNamePartsForKind(kind, True, False)
return ".".join(parts)
def IsTypemappedKind(kind):
@@ -91,13 +106,6 @@ def IsNativeOnlyKind(kind):
def GetNativeTypeName(typemapped_kind):
return _current_typemap[GetFullMojomNameForKind(typemapped_kind)]["typename"]
-def GetQualifiedNameForKind(kind):
- # Always start with an empty part to force a leading "::" on output.
- parts = [""]
- parts.extend(NamespaceToArray(kind.module.namespace))
- parts.append(kind.name)
- return "::".join(parts)
-
def GetCppType(kind):
if mojom.IsStructKind(kind) and kind.native_only:
raise Exception("Should not be reached!")
@@ -107,9 +115,9 @@ def GetCppType(kind):
return "mojo::internal::Map_Data<%s, %s>*" % (
GetCppType(kind.key_kind), GetCppType(kind.value_kind))
if mojom.IsStructKind(kind):
- return "%s_Data*" % GetNameForKind(kind, internal=True)
+ return "%s*" % GetNameForKind(kind, internal=True)
if mojom.IsUnionKind(kind):
- return "%s_Data" % GetNameForKind(kind, internal=True)
+ return "%s" % GetNameForKind(kind, internal=True)
if mojom.IsInterfaceKind(kind):
return "mojo::internal::Interface_Data"
if mojom.IsInterfaceRequestKind(kind):
@@ -119,7 +127,7 @@ def GetCppType(kind):
if mojom.IsAssociatedInterfaceRequestKind(kind):
return "mojo::internal::AssociatedInterfaceRequest_Data"
if mojom.IsEnumKind(kind):
- return "int32_t"
+ return GetNameForKind(kind, internal=True)
if mojom.IsStringKind(kind):
return "mojo::internal::String_Data*"
return _kind_to_cpp_type[kind]
@@ -280,10 +288,10 @@ def GetCppFieldType(kind):
if IsNativeOnlyKind(kind):
return "mojo::internal::ArrayPointer<uint8_t>"
if mojom.IsStructKind(kind):
- return ("mojo::internal::StructPointer<%s_Data>" %
+ return ("mojo::internal::StructPointer<%s>" %
GetNameForKind(kind, internal=True))
if mojom.IsUnionKind(kind):
- return "%s_Data" % GetNameForKind(kind, internal=True)
+ return "%s" % GetNameForKind(kind, internal=True)
if mojom.IsArrayKind(kind):
return "mojo::internal::ArrayPointer<%s>" % GetCppType(kind.kind)
if mojom.IsMapKind(kind):
@@ -298,7 +306,7 @@ def GetCppFieldType(kind):
if mojom.IsAssociatedInterfaceRequestKind(kind):
return "mojo::internal::AssociatedInterfaceRequest_Data"
if mojom.IsEnumKind(kind):
- return GetNameForKind(kind)
+ return GetNameForKind(kind, internal=True)
if mojom.IsStringKind(kind):
return "mojo::internal::StringPointer"
return _kind_to_cpp_type[kind]
@@ -308,10 +316,8 @@ def GetCppUnionFieldType(kind):
return "MojoHandle"
if mojom.IsInterfaceKind(kind):
return "uint64_t"
- if mojom.IsEnumKind(kind):
- return "int32_t"
if mojom.IsUnionKind(kind):
- return ("mojo::internal::UnionPointer<%s_Data>" %
+ return ("mojo::internal::UnionPointer<%s>" %
GetNameForKind(kind, internal=True))
return GetCppFieldType(kind)
diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/module.py b/mojo/public/tools/bindings/pylib/mojom/generate/module.py
index 4347609..cb0a010 100644
--- a/mojo/public/tools/bindings/pylib/mojom/generate/module.py
+++ b/mojo/public/tools/bindings/pylib/mojom/generate/module.py
@@ -131,6 +131,7 @@ PRIMITIVES = (
ATTRIBUTE_MIN_VERSION = 'MinVersion'
+ATTRIBUTE_EXTENSIBLE = 'Extensible'
class NamedValue(object):
@@ -445,6 +446,11 @@ class Enum(Kind):
self.fields = []
self.attributes = attributes
+ @property
+ def extensible(self):
+ return self.attributes.get(ATTRIBUTE_EXTENSIBLE, False) \
+ if self.attributes else False
+
class Module(object):
def __init__(self, name=None, namespace=None, attributes=None):
diff --git a/ui/arc/notification/arc_notification_item.cc b/ui/arc/notification/arc_notification_item.cc
index 48d3868..e13e455 100644
--- a/ui/arc/notification/arc_notification_item.cc
+++ b/ui/arc/notification/arc_notification_item.cc
@@ -127,8 +127,8 @@ void ArcNotificationItem::UpdateWithArcNotificationData(
data.progress_max * 100))));
break;
}
- DCHECK(ArcNotificationType_IsValidValue(data.type))
- << "Unsupported notification type: " << data.type;
+ DCHECK(IsKnownEnumValue(data.type)) << "Unsupported notification type: "
+ << data.type;
for (size_t i = 0; i < data.buttons.size(); i++) {
rich_data.buttons.push_back(message_center::ButtonInfo(