Mojom frontend: Start populating |resolved_concrete_value| field in mojom_types.mojom
In struct DeclaredConstant in mojom_types.mojom there is a field |resolved_concrete_value| that has been commented out and thus (obviously) not populated. The corresponding value has always been computed in the frontend Go code but we were not populating it in the intermediate representation because we were not aware of any reason to do so.
But now Vardhan will be able to use this in the new C generator. (Also I think some of the existing generators such as Dart will be able to stop computing this value themselves).
- I also added some additional tests of the existing computation of this value.
- I also fixed the name of an unrelated enum value in user_defined_types.go that I happened to notice was misnamed.
R=azani@chromium.org, vardhan@google.com
Review URL: https://codereview.chromium.org/1933563002 .
diff --git a/mojo/dart/packages/mojo/lib/mojo/bindings/types/mojom_types.mojom.dart b/mojo/dart/packages/mojo/lib/mojo/bindings/types/mojom_types.mojom.dart
index 6d7f815..f98a5a6 100644
--- a/mojo/dart/packages/mojo/lib/mojo/bindings/types/mojom_types.mojom.dart
+++ b/mojo/dart/packages/mojo/lib/mojo/bindings/types/mojom_types.mojom.dart
@@ -2002,11 +2002,12 @@
class DeclaredConstant extends bindings.Struct {
static const List<bindings.StructDataHeader> kVersions = const [
- const bindings.StructDataHeader(48, 0)
+ const bindings.StructDataHeader(64, 0)
];
DeclarationData declData = null;
Type type = null;
Value value = null;
+ Value resolvedConcreteValue = null;
DeclaredConstant() : super(kVersions.last.size);
@@ -2064,6 +2065,10 @@
'Trying to decode null union for non-nullable Value.');
}
}
+ if (mainDataHeader.version >= 0) {
+
+ result.resolvedConcreteValue = Value.decode(decoder0, 48);
+ }
return result;
}
@@ -2090,13 +2095,21 @@
"value of struct DeclaredConstant: $e";
rethrow;
}
+ try {
+ encoder0.encodeUnion(resolvedConcreteValue, 48, true);
+ } on bindings.MojoCodecError catch(e) {
+ e.message = "Error encountered while encoding field "
+ "resolvedConcreteValue of struct DeclaredConstant: $e";
+ rethrow;
+ }
}
String toString() {
return "DeclaredConstant("
"declData: $declData" ", "
"type: $type" ", "
- "value: $value" ")";
+ "value: $value" ", "
+ "resolvedConcreteValue: $resolvedConcreteValue" ")";
}
Map toJson() {
@@ -2104,6 +2117,7 @@
map["declData"] = declData;
map["type"] = type;
map["value"] = value;
+ map["resolvedConcreteValue"] = resolvedConcreteValue;
return map;
}
}
diff --git a/mojo/public/interfaces/bindings/mojom_types.mojom b/mojo/public/interfaces/bindings/mojom_types.mojom
index c9bc675..bc79282 100644
--- a/mojo/public/interfaces/bindings/mojom_types.mojom
+++ b/mojo/public/interfaces/bindings/mojom_types.mojom
@@ -368,28 +368,42 @@
struct DeclaredConstant {
DeclarationData decl_data;
- // The type must be a string, bool, or numeric type.
+ // The type must be a StringType, BOOL, a numeric type or a TypeReference
+ // whose resolved type is a MojomEnum.
Type type;
// This is the value specified in the right-hand-side of the constant
- // declaration. The value must be a literal value or a built-in constant of
- // the same type as |type| or a UserValueReference whose
- // |resolved_concrete_value| is one of those.
+ // declaration. The value must be one of the following:
+ // (a) a LiteralValue or a BuiltinConstantValue of the same type as |type|
+ // (b) a UserValueReference whose resolved value is an EnumValue of the same
+ // type as |type|, or
+ // (c) a UserValueReference whose resolved value is a different
+ // DeclaredConstant whose |resolved_concrete_value| is one of (a) or (b)
Value value;
+
// The resolved concrete value. This must be a LiteralValue, a
// BuiltinConstantValue, or UserValueReference that resolves to an
// EnumValue. It may not be a UserValueReference that resolves
- // to a DeclaredConstant. The resolved concrete value is defined as follows:
+ // to a DeclaredConstant.
+ //
+ // The resolved concrete value is defined as follows:
// If |value| is a LiteralValue, a BuiltinConstantValue or a
- // UserValueReference that refers to an EnumValue then
- // |resolved_concrete_value| is equal to |value|. Otherwise |value|
- // is a UserValueReference that refers to a different DeclaredConstant
- // and |resolved_concrete_value| is defined to be the
- // |resolved_concrete_value| of that other DeclaredConstant. This chain
- // of references must terminate in well-formed Mojom.
- // TODO(rudominer) Add this field when we have a real need for it.
- // Value? resolved_concrete_value;
+ // UserValueReference that refers to an EnumValue then the resolved
+ // concrete value is conceptually equal to |value| and this will
+ // be indicated by setting the |resolved_concrete_value| field to null.
+ //
+ // Otherwise |value| is a UserValueReference that refers to a different
+ // DeclaredConstant and in this case |resolved_concrete_value| will be
+ // non-null. It will be set to the conceptual resolved concrete value of that
+ // other DeclaredConstant (even if that other declared constant has its own
+ // |resolved_concrete_value| field set to null.) This chain of references
+ // must terminate in well-formed Mojom.
+ //
+ // In the case that |resolved_concrete_value| is set to a UserValueReference,
+ // only the |value_key| field of the UserValueReference is meaningful. The
+ // other fields should be ignored.
+ Value? resolved_concrete_value;
};
////////////////////////////////////////////////////////////////////////////
diff --git a/mojo/public/tools/bindings/mojom_tool/bin/linux64/mojom.sha1 b/mojo/public/tools/bindings/mojom_tool/bin/linux64/mojom.sha1
index fe49668..ad2de1d 100644
--- a/mojo/public/tools/bindings/mojom_tool/bin/linux64/mojom.sha1
+++ b/mojo/public/tools/bindings/mojom_tool/bin/linux64/mojom.sha1
@@ -1 +1 @@
-74937dec14c2f50951e4138cbc4e0ba61e99c8f6
\ No newline at end of file
+98f6e516f4fbabd421f6090632783f117f7dc687
\ No newline at end of file
diff --git a/mojo/public/tools/bindings/mojom_tool/bin/mac64/mojom.sha1 b/mojo/public/tools/bindings/mojom_tool/bin/mac64/mojom.sha1
index ab63c6d..4c36fff 100644
--- a/mojo/public/tools/bindings/mojom_tool/bin/mac64/mojom.sha1
+++ b/mojo/public/tools/bindings/mojom_tool/bin/mac64/mojom.sha1
@@ -1 +1 @@
-6333324072d2511f287458bd91f777fc042ea681
\ No newline at end of file
+cc88ce85a04fa888ad6322a71695aba30774a1b1
\ No newline at end of file
diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/generated/mojom_types_mojom.py b/mojo/public/tools/bindings/pylib/mojom/generate/generated/mojom_types_mojom.py
index 6e34baa..dae6e6a 100644
--- a/mojo/public/tools/bindings/pylib/mojom/generate/generated/mojom_types_mojom.py
+++ b/mojo/public/tools/bindings/pylib/mojom/generate/generated/mojom_types_mojom.py
@@ -204,6 +204,7 @@
_descriptor.SingleFieldGroup('decl_data', _descriptor.StructType(lambda: DeclarationData), 0, 0),
_descriptor.SingleFieldGroup('type', _descriptor.UnionType(lambda: Type), 1, 0),
_descriptor.SingleFieldGroup('value', _descriptor.UnionType(lambda: Value), 2, 0),
+ _descriptor.SingleFieldGroup('resolved_concrete_value', _descriptor.UnionType(lambda: Value, nullable=True), 3, 0),
],
}
diff --git a/mojom/generated/mojom_types/mojom_types.mojom.go b/mojom/generated/mojom_types/mojom_types.mojom.go
index 35f88fc..5db8a33 100644
--- a/mojom/generated/mojom_types/mojom_types.mojom.go
+++ b/mojom/generated/mojom_types/mojom_types.mojom.go
@@ -1770,11 +1770,12 @@
DeclData DeclarationData
Type Type
Value Value
+ ResolvedConcreteValue Value
}
func (s *DeclaredConstant) Encode(encoder *bindings.Encoder) error {
- encoder.StartStruct(40, 0)
+ encoder.StartStruct(56, 0)
if err := encoder.WritePointer(); err != nil {
return err
}
@@ -1793,6 +1794,13 @@
if err := s.Value.Encode(encoder); err != nil {
return err
}
+ if s.ResolvedConcreteValue == nil {
+ encoder.WriteNullUnion()
+ } else {
+ if err := s.ResolvedConcreteValue.Encode(encoder); err != nil {
+ return err
+ }
+ }
if err := encoder.Finish(); err != nil {
return err
}
@@ -1800,7 +1808,7 @@
}
var declaredConstant_Versions []bindings.DataHeader = []bindings.DataHeader{
- bindings.DataHeader{48, 0},
+ bindings.DataHeader{64, 0},
}
func (s *DeclaredConstant) Decode(decoder *bindings.Decoder) error {
@@ -1855,6 +1863,13 @@
return &bindings.ValidationError{bindings.UnexpectedNullUnion, "unexpected null union"}
}
}
+ if header.ElementsOrVersion >= 0 {
+ var err error
+ s.ResolvedConcreteValue, err = DecodeValue(decoder)
+ if err != nil {
+ return err
+ }
+ }
if err := decoder.Finish(); err != nil {
return err
}
diff --git a/mojom/mojom_tool/integration_tests/computed_data_test.go b/mojom/mojom_tool/integration_tests/computed_data_test.go
index c286efe..d18fda2 100644
--- a/mojom/mojom_tool/integration_tests/computed_data_test.go
+++ b/mojom/mojom_tool/integration_tests/computed_data_test.go
@@ -913,3 +913,133 @@
}
}
}
+
+// TestEnumComputedDataErrors test the method MojomEnum.ComputeEnumValueIntegers which
+// is invoked by ComputeFinalData. This phase occurs after resolution
+// and type validation. We test that different types of errors are correctly detected.
+func TestEnumComputedDataErrors(t *testing.T) {
+ test := singleFileTest{}
+
+ ////////////////////////////////////////////////////////////
+ // Test Case: Test that a circular reference of enum value definitions is detected.
+ ////////////////////////////////////////////////////////////
+ {
+ contents := `
+ enum MyEnum {
+ x = FIRST_VALUE,
+ y,
+ z
+ };
+ const MyEnum FIRST_VALUE = MyEnum.x;`
+ test.addTestCase(contents, []string{
+ "The reference FIRST_VALUE is being used as an enum value initializer",
+ "but it has resolved to a different enum value that itself does not yet have an integer value."})
+ }
+
+ ////////////////////////////////////////////////////////////
+ // Execute all of the test cases.
+ ////////////////////////////////////////////////////////////
+ for i, c := range test.cases {
+ // Parse anresolve the mojom input.
+ descriptor := mojom.NewMojomDescriptor()
+ specifiedName := ""
+ if c.importedFrom == nil {
+ specifiedName = c.fileName
+ }
+ parser := parser.MakeParser(c.fileName, specifiedName, c.mojomContents, descriptor, c.importedFrom)
+ parser.Parse()
+ if !parser.OK() {
+ t.Errorf("Parsing error for %s: %s", c.fileName, parser.GetError().Error())
+ continue
+ }
+ err := descriptor.Resolve()
+ if err != nil {
+ t.Errorf("Resolution error for %s: %s", c.fileName, err)
+ continue
+ }
+
+ err = descriptor.ComputeFinalData()
+
+ if err == nil {
+ t.Errorf("Data computation unexpectedly succeeded for test case %d.", i)
+ continue
+ }
+
+ got := err.Error()
+ for _, expected := range c.expectedErrors {
+ if !strings.Contains(got, expected) {
+ t.Errorf("%s:\n*****expected to contain:\n%s\n****actual\n%s", c.fileName, expected, got)
+ }
+ }
+ }
+}
+
+// TestEnumComputedData() iterates through a series of test cases.
+// For each case we expect for parsing, resolution and final data computation to succeed.
+// Then we execute a given callback test function to test that the methods
+// MojomEnum.ComputeFinalData() produced the desired result.
+func TestEnumComputedData(t *testing.T) {
+ test := singleFileSuccessTest{}
+
+ ////////////////////////////////////////////////////////////
+ // Test Case: A non-circular chain of enum value definitions.
+ ////////////////////////////////////////////////////////////
+ {
+ contents := `
+ enum MyEnum {
+ x,
+ y = FIRST_VALUE,
+ z
+ };
+ const MyEnum FIRST_VALUE = MyEnum.x;`
+
+ testFunc := func(descriptor *mojom.MojomDescriptor) error {
+ xValue := descriptor.ValuesByKey["TYPE_KEY:MyEnum.x"].(*mojom.EnumValue)
+ yValue := descriptor.ValuesByKey["TYPE_KEY:MyEnum.y"].(*mojom.EnumValue)
+ zValue := descriptor.ValuesByKey["TYPE_KEY:MyEnum.z"].(*mojom.EnumValue)
+ if xValue.ComputedIntValue != 0 {
+ return fmt.Errorf("xValue.ComputedIntValue=%d", xValue.ComputedIntValue)
+ }
+ if yValue.ComputedIntValue != 0 {
+ return fmt.Errorf("yValue.ComputedIntValue=%d", yValue.ComputedIntValue)
+ }
+ if zValue.ComputedIntValue != 1 {
+ return fmt.Errorf("zValue.ComputedIntValue=%d", zValue.ComputedIntValue)
+ }
+ return nil
+ }
+ test.addTestCase("", contents, testFunc)
+ }
+
+ ////////////////////////////////////////////////////////////
+ // Execute all of the test cases.
+ ////////////////////////////////////////////////////////////
+ for i, c := range test.cases {
+ // Parse and resolve the mojom input.
+ descriptor := mojom.NewMojomDescriptor()
+ fileName := fmt.Sprintf("file%d", i)
+ parser := parser.MakeParser(fileName, fileName, c.mojomContents, descriptor, nil)
+ parser.Parse()
+ if !parser.OK() {
+ t.Errorf("Parsing error for %s: %s", fileName, parser.GetError().Error())
+ continue
+ }
+ err := descriptor.Resolve()
+ if err != nil {
+ t.Errorf("Resolution failed for test case %d: %s", i, err.Error())
+ continue
+ }
+
+ if err := descriptor.ComputeFinalData(); err != nil {
+ t.Errorf("ComputeFinalData error for test case %d: %s", i, err.Error())
+ continue
+ }
+
+ if c.testFunc != nil {
+ if err := c.testFunc(descriptor); err != nil {
+ t.Errorf("%s:\n%s", fileName, err.Error())
+ continue
+ }
+ }
+ }
+}
diff --git a/mojom/mojom_tool/integration_tests/resolution_test.go b/mojom/mojom_tool/integration_tests/resolution_test.go
index f1434e2..8f13852 100644
--- a/mojom/mojom_tool/integration_tests/resolution_test.go
+++ b/mojom/mojom_tool/integration_tests/resolution_test.go
@@ -107,6 +107,22 @@
}
////////////////////////////////////////////////////////////
+ // Test Case: Circular reference of constants
+ ////////////////////////////////////////////////////////////
+ {
+ contents := `
+ const int32 MyConst1 = MyConst2;
+ const int32 MyConst2 = MyConst3;
+ const int32 MyConst3 = MyConst1;`
+
+ test.addTestCase(contents, []string{
+ "Use of unresolved value: \"MyConst2\"",
+ "Use of unresolved value: \"MyConst3\"",
+ "Use of unresolved value: \"MyConst1\"",
+ })
+ }
+
+ ////////////////////////////////////////////////////////////
// Execute all of the test cases.
////////////////////////////////////////////////////////////
for i, c := range test.cases {
@@ -1058,6 +1074,48 @@
}
////////////////////////////////////////////////////////////
+ // Test Case: A non-circular list of constant references.
+ ////////////////////////////////////////////////////////////
+ {
+ contents := `
+ const int32 MyConst1 = MyConst2;
+ const int32 MyConst2 = MyConst3;
+ const int32 MyConst3 = 42;`
+
+ testFunc := func(descriptor *mojom.MojomDescriptor) error {
+ myConst1 := descriptor.ValuesByKey["TYPE_KEY:MyConst1"].(*mojom.UserDefinedConstant)
+ value := myConst1.ValueRef().ResolvedConcreteValue().Value()
+ if value != int8(42) {
+ return fmt.Errorf("%v(%T) != 42", value, value)
+ }
+
+ return nil
+ }
+ test.addTestCase("", contents, testFunc)
+ }
+
+ ////////////////////////////////////////////////////////////
+ // Test Case: Circular reference of enum values
+ //
+ // NOTE: Even though we have a circular reference of enum values
+ // this case passes resolution. But the error will be detected during
+ // data computation phase when we attempt to produce integer values
+ // for the enum values. See TestEnumComputedDataError in computed_data_test.go. The reason this
+ // passes resoultion is that an enum value is a concrete value and so
+ // FIRST_VALUE has fully resolved to the concrete value MyEnum.x.
+ ////////////////////////////////////////////////////////////
+ {
+ contents := `
+ enum MyEnum {
+ x = FIRST_VALUE,
+ y,
+ z
+ };
+ const MyEnum FIRST_VALUE = MyEnum.x;`
+ test.addTestCase("", contents, nil)
+ }
+
+ ////////////////////////////////////////////////////////////
// Execute all of the test cases.
////////////////////////////////////////////////////////////
for i, c := range test.cases {
diff --git a/mojom/mojom_tool/mojom/user_defined_types.go b/mojom/mojom_tool/mojom/user_defined_types.go
index ac8c05c..a3019ad 100644
--- a/mojom/mojom_tool/mojom/user_defined_types.go
+++ b/mojom/mojom_tool/mojom/user_defined_types.go
@@ -1122,7 +1122,7 @@
// Adds an EnumValue to this enum
func (e *MojomEnum) AddEnumValue(declData DeclarationData, valueRef ValueRef) DuplicateNameError {
enumValue := new(EnumValue)
- enumValue.Init(declData, UserDefinedValueKindEnum, enumValue, valueRef)
+ enumValue.Init(declData, UserDefinedValueKindEnumValue, enumValue, valueRef)
e.Values = append(e.Values, enumValue)
e.DeclaredObjects = append(e.DeclaredObjects, enumValue)
enumValue.enumType = e
@@ -1188,14 +1188,14 @@
type UserDefinedValueKind int
const (
- UserDefinedValueKindEnum UserDefinedValueKind = iota
+ UserDefinedValueKindEnumValue UserDefinedValueKind = iota
UserDefinedValueKindDeclaredConst
UserDefinedValueKindBuiltInConst
)
func (k UserDefinedValueKind) String() string {
switch k {
- case UserDefinedValueKindEnum:
+ case UserDefinedValueKindEnumValue:
return "enum value"
case UserDefinedValueKindDeclaredConst:
return "const"
@@ -1243,7 +1243,7 @@
return err
}
- if v.thisValue.Kind() == UserDefinedValueKindEnum {
+ if v.thisValue.Kind() == UserDefinedValueKindEnumValue {
if scope.kind != ScopeEnum {
panic("An enum value may only be registered within the scope of an enum.")
}
diff --git a/mojom/mojom_tool/mojom/user_defined_types_test.go b/mojom/mojom_tool/mojom/user_defined_types_test.go
index f1dd46d..c2df376 100644
--- a/mojom/mojom_tool/mojom/user_defined_types_test.go
+++ b/mojom/mojom_tool/mojom/user_defined_types_test.go
@@ -232,7 +232,7 @@
kind UserDefinedValueKind
}{
{NewTestConstant("const", 42), UserDefinedValueKindDeclaredConst},
- {NewTestEnumValue("foo"), UserDefinedValueKindEnum},
+ {NewTestEnumValue("foo"), UserDefinedValueKindEnumValue},
{FloatInfinity, UserDefinedValueKindBuiltInConst},
}
for _, c := range cases {
diff --git a/mojom/mojom_tool/serialization/serialization.go b/mojom/mojom_tool/serialization/serialization.go
index 5bb5c2b..d330de6 100644
--- a/mojom/mojom_tool/serialization/serialization.go
+++ b/mojom/mojom_tool/serialization/serialization.go
@@ -428,9 +428,17 @@
declaredConstant.Value.Type = translateTypeRef(t.DeclaredType())
declaredConstant.Value.DeclData = *translateDeclarationData(&t.DeclarationData)
declaredConstant.Value.Value = translateValueRef(t.ValueRef())
- // TODO(rudominer) implement UserDefinedValue.resolved_concrete_value.
- // declaredConstant.ResolvedConcreteValue =
- // translateConcreteValue(t.ValueRef().ResolvedConcreteValue()))
+ // We set the |resolved_concrete_value| field only in the following situation.
+ // See the comments in mojom_types.mojom.
+ if _, ok := declaredConstant.Value.Value.(*mojom_types.ValueUserValueReference); ok {
+ // If the type of the |value| field is a UserValueReference...
+ userValueRef := t.ValueRef().(*mojom.UserValueRef)
+ if _, ok := userValueRef.ResolvedDeclaredValue().(*mojom.UserDefinedConstant); ok {
+ // and if that reference resolves to a user-defined constant.
+ declaredConstant.Value.ResolvedConcreteValue = translateConcreteValue(t.ValueRef().ResolvedConcreteValue())
+ }
+ }
+
return &declaredConstant
}
@@ -556,6 +564,29 @@
}
}
+func translateConcreteValue(cv mojom.ConcreteValue) mojom_types.Value {
+ switch cv := cv.(type) {
+ case mojom.LiteralValue:
+ return translateLiteralValue(cv)
+ // NOTE: See the comments at the top of types.go for a discussion of the difference
+ // between a value and a value reference. In this function we are translating a
+ // value, not a value reference. In the case of a LiteralValue or a
+ // BuiltInConstantValue the distinction is immaterial. But in the case of an
+ // enum value the distinction is important. Here we are building and returning
+ // a synthetic mojom_types.UserValueReference to represent the enum value.
+ // It is only the |value_key| field that needs to be populated. It does not
+ // make sense to populate the |identifier| field for example because we
+ // aren't representing any actual occrence in the .mojom file.
+ case *mojom.EnumValue:
+ return &mojom_types.ValueUserValueReference{mojom_types.UserValueReference{
+ ValueKey: stringPointer(cv.ValueKey())}}
+ case mojom.BuiltInConstantValue:
+ return translateBuiltInConstantValue(cv)
+ default:
+ panic(fmt.Sprintf("Unexpected ConcreteValue type %T", cv))
+ }
+}
+
func translateLiteralValue(v mojom.LiteralValue) *mojom_types.ValueLiteralValue {
var lv mojom_types.LiteralValue
switch v.ValueType() {
diff --git a/mojom/mojom_tool/serialization/serialization_test.go b/mojom/mojom_tool/serialization/serialization_test.go
index 545609c..c71adb0 100644
--- a/mojom/mojom_tool/serialization/serialization_test.go
+++ b/mojom/mojom_tool/serialization/serialization_test.go
@@ -995,6 +995,126 @@
}
////////////////////////////////////////////////////////////
+ // Test Case: Constants defined in terms of other constants.
+ ////////////////////////////////////////////////////////////
+ {
+
+ contents := `
+ enum Color{
+ RED, BLUE
+ };
+
+ const int32 x1 = 42;
+ const int32 x2 = x1;
+ const int32 x3 = x2;
+
+ const Color c1 = RED;
+ const Color c2 = c1;
+ const Color c3 = c2;
+ `
+ test.addTestCase("", contents)
+
+ // DeclaredMojomObjects
+ test.expectedFile().DeclaredMojomObjects.TopLevelEnums = &[]string{"TYPE_KEY:Color"}
+ test.expectedFile().DeclaredMojomObjects.TopLevelConstants = &[]string{"TYPE_KEY:x1", "TYPE_KEY:x2",
+ "TYPE_KEY:x3", "TYPE_KEY:c1", "TYPE_KEY:c2", "TYPE_KEY:c3"}
+
+ // Resolved Values
+
+ // Color.RED
+ test.expectedGraph().ResolvedValues["TYPE_KEY:Color.RED"] = &mojom_types.UserDefinedValueEnumValue{mojom_types.EnumValue{
+ DeclData: test.newDeclData("RED", "Color.RED"),
+ EnumTypeKey: "TYPE_KEY:Color",
+ IntValue: 0,
+ }}
+
+ // Color.BLUE
+ test.expectedGraph().ResolvedValues["TYPE_KEY:Color.BLUE"] = &mojom_types.UserDefinedValueEnumValue{mojom_types.EnumValue{
+ DeclData: test.newDeclData("BLUE", "Color.BLUE"),
+ EnumTypeKey: "TYPE_KEY:Color",
+ IntValue: 1,
+ }}
+
+ // x1
+ test.expectedGraph().ResolvedValues["TYPE_KEY:x1"] = &mojom_types.UserDefinedValueDeclaredConstant{mojom_types.DeclaredConstant{
+ DeclData: *test.newDeclData("x1", "x1"),
+ Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_Int32},
+ Value: &mojom_types.ValueLiteralValue{&mojom_types.LiteralValueInt8Value{42}},
+ }}
+
+ // x2
+ test.expectedGraph().ResolvedValues["TYPE_KEY:x2"] = &mojom_types.UserDefinedValueDeclaredConstant{mojom_types.DeclaredConstant{
+ DeclData: *test.newDeclData("x2", "x2"),
+ Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_Int32},
+ Value: &mojom_types.ValueUserValueReference{mojom_types.UserValueReference{
+ Identifier: "x1",
+ ValueKey: stringPointer("TYPE_KEY:x1")}},
+ ResolvedConcreteValue: &mojom_types.ValueLiteralValue{&mojom_types.LiteralValueInt8Value{42}},
+ }}
+
+ // x3
+ test.expectedGraph().ResolvedValues["TYPE_KEY:x3"] = &mojom_types.UserDefinedValueDeclaredConstant{mojom_types.DeclaredConstant{
+ DeclData: *test.newDeclData("x3", "x3"),
+ Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_Int32},
+ Value: &mojom_types.ValueUserValueReference{mojom_types.UserValueReference{
+ Identifier: "x2",
+ ValueKey: stringPointer("TYPE_KEY:x2")}},
+ ResolvedConcreteValue: &mojom_types.ValueLiteralValue{&mojom_types.LiteralValueInt8Value{42}},
+ }}
+
+ // c1
+ test.expectedGraph().ResolvedValues["TYPE_KEY:c1"] = &mojom_types.UserDefinedValueDeclaredConstant{mojom_types.DeclaredConstant{
+ DeclData: *test.newDeclData("c1", "c1"),
+ Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{
+ false, false, stringPointer("Color"), stringPointer("TYPE_KEY:Color")}},
+ Value: &mojom_types.ValueUserValueReference{mojom_types.UserValueReference{
+ Identifier: "RED",
+ ValueKey: stringPointer("TYPE_KEY:Color.RED")}},
+ }}
+
+ // c2
+ test.expectedGraph().ResolvedValues["TYPE_KEY:c2"] = &mojom_types.UserDefinedValueDeclaredConstant{mojom_types.DeclaredConstant{
+ DeclData: *test.newDeclData("c2", "c2"),
+ Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{
+ false, false, stringPointer("Color"), stringPointer("TYPE_KEY:Color")}},
+ Value: &mojom_types.ValueUserValueReference{mojom_types.UserValueReference{
+ Identifier: "c1",
+ ValueKey: stringPointer("TYPE_KEY:c1")}},
+ ResolvedConcreteValue: &mojom_types.ValueUserValueReference{mojom_types.UserValueReference{
+ ValueKey: stringPointer("TYPE_KEY:Color.RED")}},
+ }}
+
+ // c3
+ test.expectedGraph().ResolvedValues["TYPE_KEY:c3"] = &mojom_types.UserDefinedValueDeclaredConstant{mojom_types.DeclaredConstant{
+ DeclData: *test.newDeclData("c3", "c3"),
+ Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{
+ false, false, stringPointer("Color"), stringPointer("TYPE_KEY:Color")}},
+ Value: &mojom_types.ValueUserValueReference{mojom_types.UserValueReference{
+ Identifier: "c2",
+ ValueKey: stringPointer("TYPE_KEY:c2")}},
+ ResolvedConcreteValue: &mojom_types.ValueUserValueReference{mojom_types.UserValueReference{
+ ValueKey: stringPointer("TYPE_KEY:Color.RED")}},
+ }}
+
+ // ResolvedTypes
+
+ // enum Color
+ test.expectedGraph().ResolvedTypes["TYPE_KEY:Color"] = &mojom_types.UserDefinedTypeEnumType{mojom_types.MojomEnum{
+ DeclData: test.newDeclData("Color", "Color"),
+ Values: []mojom_types.EnumValue{
+ // Note(rudominer) It is a bug that we need to copy the enum values here.
+ // See https://github.com/domokit/mojo/issues/513.
+ // value RED
+ test.expectedGraph().ResolvedValues["TYPE_KEY:Color.RED"].(*mojom_types.UserDefinedValueEnumValue).Value,
+ // value BLUE
+ test.expectedGraph().ResolvedValues["TYPE_KEY:Color.BLUE"].(*mojom_types.UserDefinedValueEnumValue).Value,
+ },
+ }}
+
+ test.endTestCase()
+ }
+
+ ////////////////////////////////////////////////////////////
// Test Case
////////////////////////////////////////////////////////////
{