diff options
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( |