| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package serialization | 5 package serialization |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "fmt" | 8 "fmt" |
| 9 "mojo/public/go/bindings" | 9 "mojo/public/go/bindings" |
| 10 "mojom/mojom_parser/generated/mojom_files" | 10 "mojom/mojom_parser/generated/mojom_files" |
| 11 "mojom/mojom_parser/generated/mojom_types" | 11 "mojom/mojom_parser/generated/mojom_types" |
| 12 "mojom/mojom_parser/mojom" | 12 "mojom/mojom_parser/mojom" |
| 13 myfmt "third_party/golang/src/fmt" | 13 myfmt "third_party/golang/src/fmt" |
| 14 ) | 14 ) |
| 15 | 15 |
| 16 ////////////////////////////////////////////////// | 16 ////////////////////////////////////////////////// |
| 17 /// Mojom Descriptor Serialization | 17 /// Mojom Descriptor Serialization |
| 18 ////////////////////////////////////////////////// | 18 ////////////////////////////////////////////////// |
| 19 | 19 |
| 20 // This variable may be set to false in order to omit emitting line and | 20 // This variable may be set to false in order to omit emitting line and |
| 21 // column numbers. | 21 // column numbers. |
| 22 var EmitLineAndColumnNumbers bool = true | 22 var emitLineAndColumnNumbers bool = true |
| 23 |
| 24 // This variable may be set to false in order to omit emitting serialized |
| 25 // runtime type info. |
| 26 var emitSerializedRuntimeTypeInfo bool = true |
| 23 | 27 |
| 24 // Serialize serializes the MojomDescriptor into a binary form that is passed to
the | 28 // Serialize serializes the MojomDescriptor into a binary form that is passed to
the |
| 25 // backend of the compiler in order to invoke the code generators. | 29 // backend of the compiler in order to invoke the code generators. |
| 26 // To do this we use Mojo serialization. | 30 // To do this we use Mojo serialization. |
| 27 // If |debug| is true we also return a human-readable representation | 31 // If |debug| is true we also return a human-readable representation |
| 28 // of the serialized mojom_types.FileGraph. | 32 // of the serialized mojom_types.FileGraph. |
| 33 // This function is not thread safe. |
| 29 func Serialize(d *mojom.MojomDescriptor, debug bool) (bytes []byte, debugString
string, err error) { | 34 func Serialize(d *mojom.MojomDescriptor, debug bool) (bytes []byte, debugString
string, err error) { |
| 35 return serialize(d, debug, true, true) |
| 36 } |
| 37 |
| 38 // serialize() is a package-private version of the public method Serialize(). |
| 39 // It is intended for use in tests because it allows setting of the variables |
| 40 // emitLineAndColumnNumbers and emitSerializedRuntimeTypeInfo. |
| 41 // This function is not thread safe because it accesses the global variables |
| 42 // emitLineAndColumnNumbers and emitSerializedRuntimeTypeInfo. |
| 43 func serialize(d *mojom.MojomDescriptor, debug, |
| 44 emitLineAndColumnNumbersParam, emitSerializedRuntimeTypeInfoParam bool)
(bytes []byte, debugString string, err error) { |
| 45 saveEmitLineAndColumnNumbers := emitLineAndColumnNumbers |
| 46 emitLineAndColumnNumbers = emitLineAndColumnNumbersParam |
| 47 saveEmitSerializedRuntimeTypeInfo := emitSerializedRuntimeTypeInfo |
| 48 emitSerializedRuntimeTypeInfo = emitSerializedRuntimeTypeInfoParam |
| 49 |
| 30 fileGraph := translateDescriptor(d) | 50 fileGraph := translateDescriptor(d) |
| 31 if debug { | 51 if debug { |
| 32 debugString = myfmt.Sprintf("%#v", fileGraph) | 52 debugString = myfmt.Sprintf("%#v", fileGraph) |
| 33 } | 53 } |
| 34 encoder := bindings.NewEncoder() | 54 encoder := bindings.NewEncoder() |
| 35 fileGraph.Encode(encoder) | 55 fileGraph.Encode(encoder) |
| 36 bytes, _, err = encoder.Data() | 56 bytes, _, err = encoder.Data() |
| 57 |
| 58 emitLineAndColumnNumbers = saveEmitLineAndColumnNumbers |
| 59 emitSerializedRuntimeTypeInfo = saveEmitSerializedRuntimeTypeInfo |
| 37 return | 60 return |
| 38 } | 61 } |
| 39 | 62 |
| 40 // translateDescriptor translates from a mojom.MojomDescriptor (the pure Go | 63 // translateDescriptor translates from a mojom.MojomDescriptor (the pure Go |
| 41 // representation used by the parser) to a mojom_files.MojomFileGraph (the | 64 // representation used by the parser) to a mojom_files.MojomFileGraph (the |
| 42 // Mojo Go representation used for serialization.) | 65 // Mojo Go representation used for serialization.) |
| 43 func translateDescriptor(d *mojom.MojomDescriptor) *mojom_files.MojomFileGraph { | 66 func translateDescriptor(d *mojom.MojomDescriptor) *mojom_files.MojomFileGraph { |
| 44 fileGraph := mojom_files.MojomFileGraph{} | 67 fileGraph := mojom_files.MojomFileGraph{} |
| 45 | 68 |
| 46 // Add |files| field. | |
| 47 fileGraph.Files = make(map[string]mojom_files.MojomFile) | |
| 48 for name, file := range d.MojomFilesByName { | |
| 49 fileGraph.Files[name] = translateMojomFile(file) | |
| 50 } | |
| 51 | |
| 52 // Add |resolved_types| field. | 69 // Add |resolved_types| field. |
| 53 fileGraph.ResolvedTypes = make(map[string]mojom_types.UserDefinedType) | 70 fileGraph.ResolvedTypes = make(map[string]mojom_types.UserDefinedType) |
| 54 for key, userDefinedType := range d.TypesByKey { | 71 for key, userDefinedType := range d.TypesByKey { |
| 55 fileGraph.ResolvedTypes[key] = translateUserDefinedType(userDefi
nedType) | 72 fileGraph.ResolvedTypes[key] = translateUserDefinedType(userDefi
nedType) |
| 56 } | 73 } |
| 57 | 74 |
| 58 // Add |resolved_values| field. | 75 // Add |resolved_values| field. |
| 59 fileGraph.ResolvedValues = make(map[string]mojom_types.UserDefinedValue) | 76 fileGraph.ResolvedValues = make(map[string]mojom_types.UserDefinedValue) |
| 60 for key, userDefinedValue := range d.ValuesByKey { | 77 for key, userDefinedValue := range d.ValuesByKey { |
| 61 fileGraph.ResolvedValues[key] = translateUserDefinedValue(userDe
finedValue) | 78 fileGraph.ResolvedValues[key] = translateUserDefinedValue(userDe
finedValue) |
| 62 } | 79 } |
| 63 | 80 |
| 81 // Add |files| field. |
| 82 fileGraph.Files = make(map[string]mojom_files.MojomFile) |
| 83 for name, file := range d.MojomFilesByName { |
| 84 fileGraph.Files[name] = translateMojomFile(file, &fileGraph) |
| 85 } |
| 86 |
| 64 return &fileGraph | 87 return &fileGraph |
| 65 } | 88 } |
| 66 | 89 |
| 67 // translateMojomFile translates from a mojom.MojomFile (the pure Go | 90 // translateMojomFile translates from a mojom.MojomFile (the pure Go |
| 68 // representation used by the parser) to a mojom_files.MojomFile (the | 91 // representation used by the parser) to a mojom_files.MojomFile (the |
| 69 // Mojo Go representation used for serialization.) | 92 // Mojo Go representation used for serialization.) |
| 70 func translateMojomFile(f *mojom.MojomFile) (file mojom_files.MojomFile) { | 93 func translateMojomFile(f *mojom.MojomFile, fileGraph *mojom_files.MojomFileGrap
h) (file mojom_files.MojomFile) { |
| 71 // file_name field | 94 // file_name field |
| 72 file.FileName = f.CanonicalFileName | 95 file.FileName = f.CanonicalFileName |
| 73 | 96 |
| 74 // specified_file_name_field | 97 // specified_file_name_field |
| 75 file.SpecifiedFileName = &f.SpecifiedFileName | 98 file.SpecifiedFileName = &f.SpecifiedFileName |
| 76 | 99 |
| 77 // module_namespace field | 100 // module_namespace field |
| 78 file.ModuleNamespace = &f.ModuleNamespace.Identifier | 101 file.ModuleNamespace = &f.ModuleNamespace.Identifier |
| 79 | 102 |
| 80 // attributes field | 103 // attributes field |
| 81 if f.Attributes != nil { | 104 if f.Attributes != nil { |
| 82 file.Attributes = new([]mojom_types.Attribute) | 105 file.Attributes = new([]mojom_types.Attribute) |
| 83 for _, attr := range f.Attributes.List { | 106 for _, attr := range f.Attributes.List { |
| 84 *(file.Attributes) = append(*(file.Attributes), translat
eMojomAttribute(&attr)) | 107 *(file.Attributes) = append(*(file.Attributes), translat
eMojomAttribute(&attr)) |
| 85 } | 108 } |
| 86 } | 109 } |
| 87 | 110 |
| 88 // imports field | 111 // imports field |
| 89 if len(f.Imports) > 0 { | 112 if len(f.Imports) > 0 { |
| 90 file.Imports = new([]string) | 113 file.Imports = new([]string) |
| 91 for _, importName := range f.Imports { | 114 for _, importName := range f.Imports { |
| 92 *(file.Imports) = append(*(file.Imports), importName.Can
onicalFileName) | 115 *(file.Imports) = append(*(file.Imports), importName.Can
onicalFileName) |
| 93 } | 116 } |
| 94 } | 117 } |
| 95 | 118 |
| 96 » // declared_mojom_objects field... | 119 » // We will populate a RuntimeTypeInfo structure and then serialize it an
d |
| 120 » // the serialized bytes will form the |serialized_runtime_type_info| fie
ld |
| 121 » // of the MojomFile. |
| 122 » typeInfo := mojom_files.RuntimeTypeInfo{} |
| 123 » typeInfo.ServicesByName = make(map[string]mojom_files.ServiceTypeInfo) |
| 124 » typeInfo.TypeMap = make(map[string]mojom_types.UserDefinedType) |
| 125 |
| 126 » // We populate the declared_mojom_objects field |
| 127 » // and simultaneously we populate typeInfo.TypeMap. |
| 97 | 128 |
| 98 // Interfaces | 129 // Interfaces |
| 99 if f.Interfaces != nil && len(f.Interfaces) > 0 { | 130 if f.Interfaces != nil && len(f.Interfaces) > 0 { |
| 100 file.DeclaredMojomObjects.Interfaces = new([]string) | 131 file.DeclaredMojomObjects.Interfaces = new([]string) |
| 101 for _, intrfc := range f.Interfaces { | 132 for _, intrfc := range f.Interfaces { |
| 102 » » » *(file.DeclaredMojomObjects.Interfaces) = append(*(file.
DeclaredMojomObjects.Interfaces), intrfc.TypeKey()) | 133 » » » typeKey := intrfc.TypeKey() |
| 134 » » » *(file.DeclaredMojomObjects.Interfaces) = append(*(file.
DeclaredMojomObjects.Interfaces), typeKey) |
| 135 |
| 136 » » » addServiceTypeInfo(intrfc, &typeInfo) |
| 137 » » » typeInfo.TypeMap[typeKey] = fileGraph.ResolvedTypes[type
Key] |
| 138 » » » if intrfc.Enums != nil { |
| 139 » » » » // Add embedded enums to typeInfo.TypeMap. |
| 140 » » » » for _, enum := range intrfc.Enums { |
| 141 » » » » » typeKey := enum.TypeKey() |
| 142 » » » » » typeInfo.TypeMap[typeKey] = fileGraph.Re
solvedTypes[typeKey] |
| 143 » » » » } |
| 144 » » » } |
| 103 } | 145 } |
| 104 } | 146 } |
| 105 | 147 |
| 106 // Structs | 148 // Structs |
| 107 if f.Structs != nil && len(f.Structs) > 0 { | 149 if f.Structs != nil && len(f.Structs) > 0 { |
| 108 file.DeclaredMojomObjects.Structs = new([]string) | 150 file.DeclaredMojomObjects.Structs = new([]string) |
| 109 for _, strct := range f.Structs { | 151 for _, strct := range f.Structs { |
| 110 » » » *(file.DeclaredMojomObjects.Structs) = append(*(file.Dec
laredMojomObjects.Structs), strct.TypeKey()) | 152 » » » typeKey := strct.TypeKey() |
| 153 » » » *(file.DeclaredMojomObjects.Structs) = append(*(file.Dec
laredMojomObjects.Structs), typeKey) |
| 154 » » » typeInfo.TypeMap[typeKey] = fileGraph.ResolvedTypes[type
Key] |
| 155 » » » if strct.Enums != nil { |
| 156 » » » » // Add embedded enums to typeInfo.TypeMap. |
| 157 » » » » for _, enum := range strct.Enums { |
| 158 » » » » » typeKey := enum.TypeKey() |
| 159 » » » » » typeInfo.TypeMap[typeKey] = fileGraph.Re
solvedTypes[typeKey] |
| 160 » » » » } |
| 161 » » » } |
| 111 } | 162 } |
| 112 } | 163 } |
| 113 | 164 |
| 114 // Unions | 165 // Unions |
| 115 if f.Unions != nil && len(f.Unions) > 0 { | 166 if f.Unions != nil && len(f.Unions) > 0 { |
| 116 file.DeclaredMojomObjects.Unions = new([]string) | 167 file.DeclaredMojomObjects.Unions = new([]string) |
| 117 for _, union := range f.Unions { | 168 for _, union := range f.Unions { |
| 118 » » » *(file.DeclaredMojomObjects.Unions) = append(*(file.Decl
aredMojomObjects.Unions), union.TypeKey()) | 169 » » » typeKey := union.TypeKey() |
| 170 » » » *(file.DeclaredMojomObjects.Unions) = append(*(file.Decl
aredMojomObjects.Unions), typeKey) |
| 171 » » » typeInfo.TypeMap[typeKey] = fileGraph.ResolvedTypes[type
Key] |
| 119 } | 172 } |
| 120 } | 173 } |
| 121 | 174 |
| 122 // TopLevelEnums | 175 // TopLevelEnums |
| 123 if f.Enums != nil && len(f.Enums) > 0 { | 176 if f.Enums != nil && len(f.Enums) > 0 { |
| 124 file.DeclaredMojomObjects.TopLevelEnums = new([]string) | 177 file.DeclaredMojomObjects.TopLevelEnums = new([]string) |
| 125 for _, enum := range f.Enums { | 178 for _, enum := range f.Enums { |
| 126 » » » *(file.DeclaredMojomObjects.TopLevelEnums) = append(*(fi
le.DeclaredMojomObjects.TopLevelEnums), enum.TypeKey()) | 179 » » » typeKey := enum.TypeKey() |
| 180 » » » *(file.DeclaredMojomObjects.TopLevelEnums) = append(*(fi
le.DeclaredMojomObjects.TopLevelEnums), typeKey) |
| 181 » » » typeInfo.TypeMap[typeKey] = fileGraph.ResolvedTypes[type
Key] |
| 127 } | 182 } |
| 128 } | 183 } |
| 129 | 184 |
| 130 // TopLevelConstants | 185 // TopLevelConstants |
| 131 if f.Constants != nil && len(f.Constants) > 0 { | 186 if f.Constants != nil && len(f.Constants) > 0 { |
| 132 file.DeclaredMojomObjects.TopLevelConstants = new([]string) | 187 file.DeclaredMojomObjects.TopLevelConstants = new([]string) |
| 133 for _, constant := range f.Constants { | 188 for _, constant := range f.Constants { |
| 134 *(file.DeclaredMojomObjects.TopLevelConstants) = append(
*(file.DeclaredMojomObjects.TopLevelConstants), constant.ValueKey()) | 189 *(file.DeclaredMojomObjects.TopLevelConstants) = append(
*(file.DeclaredMojomObjects.TopLevelConstants), constant.ValueKey()) |
| 135 } | 190 } |
| 136 } | 191 } |
| 137 | 192 |
| 138 // TODO(rudominer) Do we need the EmbeddedEnums and EmbeddedConstants | 193 // TODO(rudominer) Do we need the EmbeddedEnums and EmbeddedConstants |
| 139 // fields in KeysByType. It seems these fields are not currently being | 194 // fields in KeysByType. It seems these fields are not currently being |
| 140 // used in mojom_translator.py. | 195 // used in mojom_translator.py. |
| 141 | 196 |
| 197 // SerializedRuntimeTypeInfo |
| 198 if emitSerializedRuntimeTypeInfo { |
| 199 encoder := bindings.NewEncoder() |
| 200 typeInfo.Encode(encoder) |
| 201 bytes, _, err := encoder.Data() |
| 202 if err != nil { |
| 203 panic(fmt.Sprintf("Error while serializing runtimeTypeIn
fo: %s", err.Error())) |
| 204 } |
| 205 file.SerializedRuntimeTypeInfo = &bytes |
| 206 } |
| 207 |
| 142 return | 208 return |
| 143 } | 209 } |
| 144 | 210 |
| 211 // addServiceTypeInfo will add a ServiceTypeInfo to the ServicesByName field of
|typeInfo| corresponding |
| 212 // to |intrfc| if |intrfc| is a top-level interface, meaning that it has a non-n
il service name. In that |
| 213 // case this method returns true. Otherwise this method will do nothing and retu
rn fals. |
| 214 func addServiceTypeInfo(intrfc *mojom.MojomInterface, typeInfo *mojom_files.Runt
imeTypeInfo) (isTopLevel bool) { |
| 215 isTopLevel = intrfc.ServiceName != nil |
| 216 if isTopLevel { |
| 217 serviceTypeInfo := mojom_files.ServiceTypeInfo{} |
| 218 serviceTypeInfo.TopLevelInterface = intrfc.TypeKey() |
| 219 serviceTypeInfo.CompleteTypeSet = intrfc.FindReachableTypes() |
| 220 typeInfo.ServicesByName[*intrfc.ServiceName] = serviceTypeInfo |
| 221 } |
| 222 return |
| 223 } |
| 224 |
| 145 // translateUserDefinedType translates from a mojom.UserDefinedType (the pure Go | 225 // translateUserDefinedType translates from a mojom.UserDefinedType (the pure Go |
| 146 // representation used by the parser) to a mojom_types.UserDefinedType (the | 226 // representation used by the parser) to a mojom_types.UserDefinedType (the |
| 147 // Mojo Go representation used for serialization.) | 227 // Mojo Go representation used for serialization.) |
| 148 func translateUserDefinedType(t mojom.UserDefinedType) mojom_types.UserDefinedTy
pe { | 228 func translateUserDefinedType(t mojom.UserDefinedType) mojom_types.UserDefinedTy
pe { |
| 149 switch p := t.(type) { | 229 switch p := t.(type) { |
| 150 case *mojom.MojomStruct: | 230 case *mojom.MojomStruct: |
| 151 return &mojom_types.UserDefinedTypeStructType{translateMojomStru
ct(p)} | 231 return &mojom_types.UserDefinedTypeStructType{translateMojomStru
ct(p)} |
| 152 case *mojom.MojomInterface: | 232 case *mojom.MojomInterface: |
| 153 return translateMojomInterface(p) | 233 return translateMojomInterface(p) |
| 154 case *mojom.MojomEnum: | 234 case *mojom.MojomEnum: |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 537 // in a different field. | 617 // in a different field. |
| 538 case *mojom.EnumValue: | 618 case *mojom.EnumValue: |
| 539 default: | 619 default: |
| 540 declData.ContainerTypeKey = stringPointer(containingType
.TypeKey()) | 620 declData.ContainerTypeKey = stringPointer(containingType
.TypeKey()) |
| 541 } | 621 } |
| 542 } | 622 } |
| 543 | 623 |
| 544 // source_file_info | 624 // source_file_info |
| 545 declData.SourceFileInfo = new(mojom_types.SourceFileInfo) | 625 declData.SourceFileInfo = new(mojom_types.SourceFileInfo) |
| 546 declData.SourceFileInfo.FileName = d.OwningFile().CanonicalFileName | 626 declData.SourceFileInfo.FileName = d.OwningFile().CanonicalFileName |
| 547 » if EmitLineAndColumnNumbers { | 627 » if emitLineAndColumnNumbers { |
| 548 declData.SourceFileInfo.LineNumber = d.LineNumber() | 628 declData.SourceFileInfo.LineNumber = d.LineNumber() |
| 549 declData.SourceFileInfo.ColumnNumber = d.ColumnNumber() | 629 declData.SourceFileInfo.ColumnNumber = d.ColumnNumber() |
| 550 } | 630 } |
| 551 return &declData | 631 return &declData |
| 552 } | 632 } |
| 553 | 633 |
| 554 // Returns nil if there are no contained declarations | 634 // Returns nil if there are no contained declarations |
| 555 func translateContainedDeclarations(container *mojom.NestedDeclarations) *mojom_
types.ContainedDeclarations { | 635 func translateContainedDeclarations(container *mojom.NestedDeclarations) *mojom_
types.ContainedDeclarations { |
| 556 if container.Enums == nil && container.Constants == nil { | 636 if container.Enums == nil && container.Constants == nil { |
| 557 return nil | 637 return nil |
| (...skipping 20 matching lines...) Expand all Loading... |
| 578 | 658 |
| 579 // stringPointer is a convenience function for creating a pointer to a string wh
ose value | 659 // stringPointer is a convenience function for creating a pointer to a string wh
ose value |
| 580 // is the specified string. It may be used in situations where the compiler will | 660 // is the specified string. It may be used in situations where the compiler will |
| 581 // not allow you to take the address of a string value directly, such as the | 661 // not allow you to take the address of a string value directly, such as the |
| 582 // return value of a function. It is necessary to create pointers to strings bec
ause | 662 // return value of a function. It is necessary to create pointers to strings bec
ause |
| 583 // that is how the Mojom type |string?| (i.e. nullable string) is represented in | 663 // that is how the Mojom type |string?| (i.e. nullable string) is represented in |
| 584 // in the Mojom Go bindings. | 664 // in the Mojom Go bindings. |
| 585 func stringPointer(s string) *string { | 665 func stringPointer(s string) *string { |
| 586 return &s | 666 return &s |
| 587 } | 667 } |
| OLD | NEW |