Chromium Code Reviews| 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 | 23 |
| 24 // This variable may be set to false in order to omit emitting serialized | |
| 25 // runtime type info. | |
| 26 var EmitSerializedRuntimeTypeInfo bool = true | |
|
azani
2016/02/11 19:45:48
As discussed, make this private and create a packa
rudominer
2016/02/11 20:16:11
Done.
| |
| 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. |
| 29 func Serialize(d *mojom.MojomDescriptor, debug bool) (bytes []byte, debugString string, err error) { | 33 func Serialize(d *mojom.MojomDescriptor, debug bool) (bytes []byte, debugString string, err error) { |
| 30 fileGraph := translateDescriptor(d) | 34 fileGraph := translateDescriptor(d) |
| 31 if debug { | 35 if debug { |
| 32 debugString = myfmt.Sprintf("%#v", fileGraph) | 36 debugString = myfmt.Sprintf("%#v", fileGraph) |
| 33 } | 37 } |
| 34 encoder := bindings.NewEncoder() | 38 encoder := bindings.NewEncoder() |
| 35 fileGraph.Encode(encoder) | 39 fileGraph.Encode(encoder) |
| 36 bytes, _, err = encoder.Data() | 40 bytes, _, err = encoder.Data() |
| 37 return | 41 return |
| 38 } | 42 } |
| 39 | 43 |
| 40 // translateDescriptor translates from a mojom.MojomDescriptor (the pure Go | 44 // translateDescriptor translates from a mojom.MojomDescriptor (the pure Go |
| 41 // representation used by the parser) to a mojom_files.MojomFileGraph (the | 45 // representation used by the parser) to a mojom_files.MojomFileGraph (the |
| 42 // Mojo Go representation used for serialization.) | 46 // Mojo Go representation used for serialization.) |
| 43 func translateDescriptor(d *mojom.MojomDescriptor) *mojom_files.MojomFileGraph { | 47 func translateDescriptor(d *mojom.MojomDescriptor) *mojom_files.MojomFileGraph { |
| 44 fileGraph := mojom_files.MojomFileGraph{} | 48 fileGraph := mojom_files.MojomFileGraph{} |
| 45 | 49 |
| 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. | 50 // Add |resolved_types| field. |
| 53 fileGraph.ResolvedTypes = make(map[string]mojom_types.UserDefinedType) | 51 fileGraph.ResolvedTypes = make(map[string]mojom_types.UserDefinedType) |
| 54 for key, userDefinedType := range d.TypesByKey { | 52 for key, userDefinedType := range d.TypesByKey { |
| 55 fileGraph.ResolvedTypes[key] = translateUserDefinedType(userDefi nedType) | 53 fileGraph.ResolvedTypes[key] = translateUserDefinedType(userDefi nedType) |
| 56 } | 54 } |
| 57 | 55 |
| 58 // Add |resolved_values| field. | 56 // Add |resolved_values| field. |
| 59 fileGraph.ResolvedValues = make(map[string]mojom_types.UserDefinedValue) | 57 fileGraph.ResolvedValues = make(map[string]mojom_types.UserDefinedValue) |
| 60 for key, userDefinedValue := range d.ValuesByKey { | 58 for key, userDefinedValue := range d.ValuesByKey { |
| 61 fileGraph.ResolvedValues[key] = translateUserDefinedValue(userDe finedValue) | 59 fileGraph.ResolvedValues[key] = translateUserDefinedValue(userDe finedValue) |
| 62 } | 60 } |
| 63 | 61 |
| 62 // Add |files| field. | |
| 63 fileGraph.Files = make(map[string]mojom_files.MojomFile) | |
| 64 for name, file := range d.MojomFilesByName { | |
| 65 fileGraph.Files[name] = translateMojomFile(file, &fileGraph) | |
| 66 } | |
| 67 | |
| 64 return &fileGraph | 68 return &fileGraph |
| 65 } | 69 } |
| 66 | 70 |
| 67 // translateMojomFile translates from a mojom.MojomFile (the pure Go | 71 // translateMojomFile translates from a mojom.MojomFile (the pure Go |
| 68 // representation used by the parser) to a mojom_files.MojomFile (the | 72 // representation used by the parser) to a mojom_files.MojomFile (the |
| 69 // Mojo Go representation used for serialization.) | 73 // Mojo Go representation used for serialization.) |
| 70 func translateMojomFile(f *mojom.MojomFile) (file mojom_files.MojomFile) { | 74 func translateMojomFile(f *mojom.MojomFile, fileGraph *mojom_files.MojomFileGrap h) (file mojom_files.MojomFile) { |
| 71 // file_name field | 75 // file_name field |
| 72 file.FileName = f.CanonicalFileName | 76 file.FileName = f.CanonicalFileName |
| 73 | 77 |
| 74 // specified_file_name_field | 78 // specified_file_name_field |
| 75 file.SpecifiedFileName = &f.SpecifiedFileName | 79 file.SpecifiedFileName = &f.SpecifiedFileName |
| 76 | 80 |
| 77 // module_namespace field | 81 // module_namespace field |
| 78 file.ModuleNamespace = &f.ModuleNamespace.Identifier | 82 file.ModuleNamespace = &f.ModuleNamespace.Identifier |
| 79 | 83 |
| 80 // attributes field | 84 // attributes field |
| 81 if f.Attributes != nil { | 85 if f.Attributes != nil { |
| 82 file.Attributes = new([]mojom_types.Attribute) | 86 file.Attributes = new([]mojom_types.Attribute) |
| 83 for _, attr := range f.Attributes.List { | 87 for _, attr := range f.Attributes.List { |
| 84 *(file.Attributes) = append(*(file.Attributes), translat eMojomAttribute(&attr)) | 88 *(file.Attributes) = append(*(file.Attributes), translat eMojomAttribute(&attr)) |
| 85 } | 89 } |
| 86 } | 90 } |
| 87 | 91 |
| 88 // imports field | 92 // imports field |
| 89 if len(f.Imports) > 0 { | 93 if len(f.Imports) > 0 { |
| 90 file.Imports = new([]string) | 94 file.Imports = new([]string) |
| 91 for _, importName := range f.Imports { | 95 for _, importName := range f.Imports { |
| 92 *(file.Imports) = append(*(file.Imports), importName.Can onicalFileName) | 96 *(file.Imports) = append(*(file.Imports), importName.Can onicalFileName) |
| 93 } | 97 } |
| 94 } | 98 } |
| 95 | 99 |
| 96 » // declared_mojom_objects field... | 100 » // We will populate a RuntimeTypeInfo structure and then serialize it an d |
| 101 » // the serialized bytes will form the |serialized_runtime_type_info| fie ld | |
| 102 » // of the MojomFile. | |
| 103 » typeInfo := mojom_files.RuntimeTypeInfo{} | |
| 104 » typeInfo.ServicesByName = make(map[string]mojom_files.ServiceTypeInfo) | |
| 105 » typeInfo.TypeMap = make(map[string]mojom_types.UserDefinedType) | |
| 106 | |
| 107 » // We populate the declared_mojom_objects field | |
| 108 » // and simultaneously we populate typeInfo.TypeMap. | |
| 97 | 109 |
| 98 // Interfaces | 110 // Interfaces |
| 99 if f.Interfaces != nil && len(f.Interfaces) > 0 { | 111 if f.Interfaces != nil && len(f.Interfaces) > 0 { |
| 100 file.DeclaredMojomObjects.Interfaces = new([]string) | 112 file.DeclaredMojomObjects.Interfaces = new([]string) |
| 101 for _, intrfc := range f.Interfaces { | 113 for _, intrfc := range f.Interfaces { |
| 102 » » » *(file.DeclaredMojomObjects.Interfaces) = append(*(file. DeclaredMojomObjects.Interfaces), intrfc.TypeKey()) | 114 » » » typeKey := intrfc.TypeKey() |
| 115 » » » *(file.DeclaredMojomObjects.Interfaces) = append(*(file. DeclaredMojomObjects.Interfaces), typeKey) | |
| 116 | |
| 117 » » » addServiceTypeInfo(intrfc, &typeInfo) | |
| 118 » » » typeInfo.TypeMap[typeKey] = fileGraph.ResolvedTypes[type Key] | |
| 119 » » » if intrfc.Enums != nil { | |
| 120 » » » » // Add embedded enums to typeInfo.TypeMap. | |
| 121 » » » » for _, enum := range intrfc.Enums { | |
| 122 » » » » » typeKey := enum.TypeKey() | |
| 123 » » » » » typeInfo.TypeMap[typeKey] = fileGraph.Re solvedTypes[typeKey] | |
| 124 » » » » } | |
| 125 » » » } | |
| 103 } | 126 } |
| 104 } | 127 } |
| 105 | 128 |
| 106 // Structs | 129 // Structs |
| 107 if f.Structs != nil && len(f.Structs) > 0 { | 130 if f.Structs != nil && len(f.Structs) > 0 { |
| 108 file.DeclaredMojomObjects.Structs = new([]string) | 131 file.DeclaredMojomObjects.Structs = new([]string) |
| 109 for _, strct := range f.Structs { | 132 for _, strct := range f.Structs { |
| 110 » » » *(file.DeclaredMojomObjects.Structs) = append(*(file.Dec laredMojomObjects.Structs), strct.TypeKey()) | 133 » » » typeKey := strct.TypeKey() |
| 134 » » » *(file.DeclaredMojomObjects.Structs) = append(*(file.Dec laredMojomObjects.Structs), typeKey) | |
| 135 » » » typeInfo.TypeMap[typeKey] = fileGraph.ResolvedTypes[type Key] | |
| 136 » » » if strct.Enums != nil { | |
| 137 » » » » // Add embedded enums to typeInfo.TypeMap. | |
| 138 » » » » for _, enum := range strct.Enums { | |
| 139 » » » » » typeKey := enum.TypeKey() | |
| 140 » » » » » typeInfo.TypeMap[typeKey] = fileGraph.Re solvedTypes[typeKey] | |
| 141 » » » » } | |
| 142 » » » } | |
| 111 } | 143 } |
| 112 } | 144 } |
| 113 | 145 |
| 114 // Unions | 146 // Unions |
| 115 if f.Unions != nil && len(f.Unions) > 0 { | 147 if f.Unions != nil && len(f.Unions) > 0 { |
| 116 file.DeclaredMojomObjects.Unions = new([]string) | 148 file.DeclaredMojomObjects.Unions = new([]string) |
| 117 for _, union := range f.Unions { | 149 for _, union := range f.Unions { |
| 118 » » » *(file.DeclaredMojomObjects.Unions) = append(*(file.Decl aredMojomObjects.Unions), union.TypeKey()) | 150 » » » typeKey := union.TypeKey() |
| 151 » » » *(file.DeclaredMojomObjects.Unions) = append(*(file.Decl aredMojomObjects.Unions), typeKey) | |
| 152 » » » typeInfo.TypeMap[typeKey] = fileGraph.ResolvedTypes[type Key] | |
| 119 } | 153 } |
| 120 } | 154 } |
| 121 | 155 |
| 122 // TopLevelEnums | 156 // TopLevelEnums |
| 123 if f.Enums != nil && len(f.Enums) > 0 { | 157 if f.Enums != nil && len(f.Enums) > 0 { |
| 124 file.DeclaredMojomObjects.TopLevelEnums = new([]string) | 158 file.DeclaredMojomObjects.TopLevelEnums = new([]string) |
| 125 for _, enum := range f.Enums { | 159 for _, enum := range f.Enums { |
| 126 » » » *(file.DeclaredMojomObjects.TopLevelEnums) = append(*(fi le.DeclaredMojomObjects.TopLevelEnums), enum.TypeKey()) | 160 » » » typeKey := enum.TypeKey() |
| 161 » » » *(file.DeclaredMojomObjects.TopLevelEnums) = append(*(fi le.DeclaredMojomObjects.TopLevelEnums), typeKey) | |
| 162 » » » typeInfo.TypeMap[typeKey] = fileGraph.ResolvedTypes[type Key] | |
| 127 } | 163 } |
| 128 } | 164 } |
| 129 | 165 |
| 130 // TopLevelConstants | 166 // TopLevelConstants |
| 131 if f.Constants != nil && len(f.Constants) > 0 { | 167 if f.Constants != nil && len(f.Constants) > 0 { |
| 132 file.DeclaredMojomObjects.TopLevelConstants = new([]string) | 168 file.DeclaredMojomObjects.TopLevelConstants = new([]string) |
| 133 for _, constant := range f.Constants { | 169 for _, constant := range f.Constants { |
| 134 *(file.DeclaredMojomObjects.TopLevelConstants) = append( *(file.DeclaredMojomObjects.TopLevelConstants), constant.ValueKey()) | 170 *(file.DeclaredMojomObjects.TopLevelConstants) = append( *(file.DeclaredMojomObjects.TopLevelConstants), constant.ValueKey()) |
| 135 } | 171 } |
| 136 } | 172 } |
| 137 | 173 |
| 138 // TODO(rudominer) Do we need the EmbeddedEnums and EmbeddedConstants | 174 // TODO(rudominer) Do we need the EmbeddedEnums and EmbeddedConstants |
| 139 // fields in KeysByType. It seems these fields are not currently being | 175 // fields in KeysByType. It seems these fields are not currently being |
| 140 // used in mojom_translator.py. | 176 // used in mojom_translator.py. |
| 141 | 177 |
| 178 // SerializedRuntimeTypeInfo | |
| 179 if EmitSerializedRuntimeTypeInfo { | |
| 180 encoder := bindings.NewEncoder() | |
| 181 typeInfo.Encode(encoder) | |
| 182 bytes, _, err := encoder.Data() | |
| 183 if err != nil { | |
| 184 panic(fmt.Sprintf("Error while serializing runtimeTypeIn fo: %s", err.Error())) | |
| 185 } | |
| 186 file.SerializedRuntimeTypeInfo = &bytes | |
| 187 } | |
| 188 | |
| 142 return | 189 return |
| 143 } | 190 } |
| 144 | 191 |
| 192 // addServiceTypeInfo will add a ServiceTypeInfo to the ServicesByName field of |typeInfo| corresponding | |
| 193 // to |intrfc| if |intrfc| is a top-level interface, meaning that it has a non-n il service name. In that | |
| 194 // case this method returns true. Otherwise this method will do nothing and retu rn fals. | |
| 195 func addServiceTypeInfo(intrfc *mojom.MojomInterface, typeInfo *mojom_files.Runt imeTypeInfo) (isTopLevel bool) { | |
| 196 isTopLevel = intrfc.ServiceName != nil | |
| 197 if isTopLevel { | |
| 198 serviceTypeInfo := mojom_files.ServiceTypeInfo{} | |
| 199 serviceTypeInfo.TopLevelInterface = intrfc.TypeKey() | |
| 200 serviceTypeInfo.CompleteTypeSet = intrfc.FindReachableTypes() | |
| 201 typeInfo.ServicesByName[*intrfc.ServiceName] = serviceTypeInfo | |
| 202 } | |
| 203 return | |
| 204 } | |
| 205 | |
| 145 // translateUserDefinedType translates from a mojom.UserDefinedType (the pure Go | 206 // translateUserDefinedType translates from a mojom.UserDefinedType (the pure Go |
| 146 // representation used by the parser) to a mojom_types.UserDefinedType (the | 207 // representation used by the parser) to a mojom_types.UserDefinedType (the |
| 147 // Mojo Go representation used for serialization.) | 208 // Mojo Go representation used for serialization.) |
| 148 func translateUserDefinedType(t mojom.UserDefinedType) mojom_types.UserDefinedTy pe { | 209 func translateUserDefinedType(t mojom.UserDefinedType) mojom_types.UserDefinedTy pe { |
| 149 switch p := t.(type) { | 210 switch p := t.(type) { |
| 150 case *mojom.MojomStruct: | 211 case *mojom.MojomStruct: |
| 151 return &mojom_types.UserDefinedTypeStructType{translateMojomStru ct(p)} | 212 return &mojom_types.UserDefinedTypeStructType{translateMojomStru ct(p)} |
| 152 case *mojom.MojomInterface: | 213 case *mojom.MojomInterface: |
| 153 return translateMojomInterface(p) | 214 return translateMojomInterface(p) |
| 154 case *mojom.MojomEnum: | 215 case *mojom.MojomEnum: |
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 578 | 639 |
| 579 // stringPointer is a convenience function for creating a pointer to a string wh ose value | 640 // 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 | 641 // 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 | 642 // 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 | 643 // 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 | 644 // that is how the Mojom type |string?| (i.e. nullable string) is represented in |
| 584 // in the Mojom Go bindings. | 645 // in the Mojom Go bindings. |
| 585 func stringPointer(s string) *string { | 646 func stringPointer(s string) *string { |
| 586 return &s | 647 return &s |
| 587 } | 648 } |
| OLD | NEW |