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 |