New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 738142 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Last visit > 30 days ago
Closed: Jun 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug



Sign in to add a comment

Compilation failure: Setting default value for fields whose types are typemapped enums

Project Member Reported by yzshen@chromium.org, Jun 29 2017

Issue description

Consider the following example:

// Typemapped to "MappedFooEnum":
enum FooEnum {
  VALUE_1,
  VALUE_2
};

struct BarStruct {
  FooEnum = VALUE_1;
};

In this case our generated code fails compilation because it tries to assign FIELD_1 to MappedFooEnum in the constructor of BarStruct.
 

Comment 1 by yzshen@chromium.org, Jun 29 2017


I was thinking that I could use EnumTraits<FooEnum, MappedFooEnum>::FromMojom() to convert FIELD_1 to its corresponding value in MappedFooEnum in the constructor of BarStruct. But I then realized that it still doesn't feel right:

EnumTraits<>::FromMojom() is used for de-seralization. Therefore, it could include validation logic that only applies when the value is received from a message pipe, but not when a local struct is constructed. For example,

// Typemapped to "MappedFooEnum":
//  MappedFooEnum {
//    MAPPED_INVALID_VALUE,
//    MAPPED_VALUE_1,
//    MAPPED_VALUE_2
//  } 
enum FooEnum {
  INVALID_VALUE,
  VALUE_1,
  VALUE_2
};

Struct BarStruct {
  FooEnum = INVALID_VALUE
};

It is conceivable that INVALID_VALUE is not allowed when you pass a FooEnum over the wire, so you write the following EnumTraits:

bool EnumTraits<FooEnum, MappedFooEnum>::FromMojom(FooEnum input, MappedFooEnum* output) {
  // Always reject an incoming INVALID_VALUE
  if (input == INVALID_VALUE)
    return false;
  ...
};

Considering all these, I lean towards not supporting default value when an enum is typemapped. WDYT?

Comment 2 by roc...@chromium.org, Jun 29 2017

Using EnumTraits seems reasonable to me. Validation logic should in
practice only cause the traits to return false from Read right? i.e. we
definitely don't want traits DCHECKing or anything like that.

Comment 3 by yzshen@chromium.org, Jun 29 2017

If the EnumTraits returns false, what should we use to initialize the field?

We don't require the EnumTraits to always update the output field on failure. During deserialization, we always discard the output on failure so whether it is touched doesn't matter.

It seems "local type conversion" and "deserializing a value off the wire" are two different things. It might be confusing if we use EnumTraits for both purposes.

WDYT? Thanks!


Hmmm.  Forbidding defaults in mojo will mean that if any language has a typemap, all other languages will need a typemap in order to specify the defaults.  So on an overall consistency basis, I don't think that's the right choice.  And I wouldn't expect that an option listed in the .mojom file would be invalid coming over the wire.  

Having said that, from my perspective as a pure C++ consumer, I'm fine with it :-}.
I'll also note that I'd expect *Traits to be fairly liberal in what it accepts, with security or similar restrictions implemented in the service implementation (as those would be variable depending on the source of the request).  Do you have an example of a case in which *Traits be be likely to return false for a default value?

Comment 6 by yzshen@chromium.org, Jun 29 2017

> And I wouldn't expect that an option listed in the .mojom file would be invalid coming over the wire.  

I think it is not impossible. A value is defined as an invalid initial state, and the user would like to enforce that this value is never used in messages.

An example that is not directly related but I think it is kind of similar:


Struct Foo {};
Struct Bar {
  Foo foo;
};

The generated code initializes |foo| as null, but because |foo| is defined as non-nullable. It is illegal if you send a Bar struct with a null |foo| field over the wire.

> Do you have an example of a case in which *Traits be be likely to return false for a default value?
I could look and see whether I could find one. :)

Comment 7 by yzshen@chromium.org, Jun 29 2017

> > Do you have an example of a case in which *Traits be be likely to return false for a default value?
> I could look and see whether I could find one. :)
Okay, the answer is that I couldn't find any real-world example in our codebase.

I think I am no longer against the idea of supporting this. :) I will put together a patch. And I will CHECK if EnumTraits<>::FromMojom returns false. WDYT?

Comment 9 by yzshen@chromium.org, Jun 30 2017

Status: Fixed (was: Untriaged)

Sign in to add a comment