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 "bytes" | 8 "bytes" |
9 "compress/gzip" | 9 "compress/gzip" |
10 "encoding/base64" | 10 "encoding/base64" |
(...skipping 14 matching lines...) Expand all Loading... |
25 var emitLineAndColumnNumbers bool = true | 25 var emitLineAndColumnNumbers bool = true |
26 | 26 |
27 // This variable may be set to false in order to omit emitting computed | 27 // This variable may be set to false in order to omit emitting computed |
28 // packing. This is useful in tests. | 28 // packing. This is useful in tests. |
29 var emitComputedPackingData bool = true | 29 var emitComputedPackingData bool = true |
30 | 30 |
31 // This variable may be set to false in order to omit emitting serialized | 31 // This variable may be set to false in order to omit emitting serialized |
32 // runtime type info. This is useful in tests. | 32 // runtime type info. This is useful in tests. |
33 var emitSerializedRuntimeTypeInfo bool = true | 33 var emitSerializedRuntimeTypeInfo bool = true |
34 | 34 |
35 // By default we do not populate the complete type set of each top-level interfa
ce | |
36 // because doing so is expensive and we are not currently using the the data. | |
37 var populateCompleteTypeSet bool = false | |
38 | |
39 // Serialize serializes the MojomDescriptor into a binary form that is passed to
the | 35 // Serialize serializes the MojomDescriptor into a binary form that is passed to
the |
40 // backend of the compiler in order to invoke the code generators. | 36 // backend of the compiler in order to invoke the code generators. |
41 // To do this we use Mojo serialization. | 37 // To do this we use Mojo serialization. |
42 // If |debug| is true we also return a human-readable representation | 38 // If |debug| is true we also return a human-readable representation |
43 // of the serialized mojom_types.FileGraph. | 39 // of the serialized mojom_types.FileGraph. |
44 // This function is not thread safe. | 40 // This function is not thread safe. |
45 func Serialize(d *mojom.MojomDescriptor, debug bool) (bytes []byte, debugString
string, err error) { | 41 func Serialize(d *mojom.MojomDescriptor, debug bool) (bytes []byte, debugString
string, err error) { |
46 » return serialize(d, debug, true, true, true, false) | 42 » return serialize(d, debug, true, true, true) |
47 } | 43 } |
48 | 44 |
49 // serialize() is a package-private version of the public method Serialize(). | 45 // serialize() is a package-private version of the public method Serialize(). |
50 // It is intended for use in tests because it allows setting of the variables | 46 // It is intended for use in tests because it allows setting of the variables |
51 // emitLineAndColumnNumbers, emitComputedPackingData, emitSerializedRuntimeTypeI
nfo | 47 // emitLineAndColumnNumbers, emitComputedPackingData and emitSerializedRuntimeTy
peInfo. |
52 // and populateCompleteTypeSet. | |
53 // This function is not thread safe because it sets and accesses these global | 48 // This function is not thread safe because it sets and accesses these global |
54 // variables. | 49 // variables. |
55 func serialize(d *mojom.MojomDescriptor, debug, | 50 func serialize(d *mojom.MojomDescriptor, debug, |
56 » emitLineAndColumnNumbersParam, emitComputedPackingDataParam, emitSeriali
zedRuntimeTypeInfoParam, | 51 » emitLineAndColumnNumbersParam, emitComputedPackingDataParam, |
57 » populateCompleteTypeSetParam bool) (bytes []byte, debugString string, er
r error) { | 52 » emitSerializedRuntimeTypeInfoParam bool) (bytes []byte, debugString stri
ng, err error) { |
58 | 53 |
59 // Save the global state and then set it based on the parameters. | 54 // Save the global state and then set it based on the parameters. |
60 saveEmitLineAndColumnNumbers := emitLineAndColumnNumbers | 55 saveEmitLineAndColumnNumbers := emitLineAndColumnNumbers |
61 emitLineAndColumnNumbers = emitLineAndColumnNumbersParam | 56 emitLineAndColumnNumbers = emitLineAndColumnNumbersParam |
62 saveEmitComputedPackingData := emitComputedPackingData | 57 saveEmitComputedPackingData := emitComputedPackingData |
63 emitComputedPackingData = emitComputedPackingDataParam | 58 emitComputedPackingData = emitComputedPackingDataParam |
64 saveEmitSerializedRuntimeTypeInfo := emitSerializedRuntimeTypeInfo | 59 saveEmitSerializedRuntimeTypeInfo := emitSerializedRuntimeTypeInfo |
65 emitSerializedRuntimeTypeInfo = emitSerializedRuntimeTypeInfoParam | 60 emitSerializedRuntimeTypeInfo = emitSerializedRuntimeTypeInfoParam |
66 savePopulateCompleteTypeSet := populateCompleteTypeSet | |
67 populateCompleteTypeSet = populateCompleteTypeSetParam | |
68 | 61 |
69 fileGraph := translateDescriptor(d) | 62 fileGraph := translateDescriptor(d) |
70 if debug { | 63 if debug { |
71 debugString = myfmt.Sprintf("%#v", fileGraph) | 64 debugString = myfmt.Sprintf("%#v", fileGraph) |
72 } | 65 } |
73 encoder := bindings.NewEncoder() | 66 encoder := bindings.NewEncoder() |
74 encoder.SetDeterministic(true) | 67 encoder.SetDeterministic(true) |
75 fileGraph.Encode(encoder) | 68 fileGraph.Encode(encoder) |
76 bytes, _, err = encoder.Data() | 69 bytes, _, err = encoder.Data() |
77 | 70 |
78 // Restore the original values of the global state. | 71 // Restore the original values of the global state. |
79 emitLineAndColumnNumbers = saveEmitLineAndColumnNumbers | 72 emitLineAndColumnNumbers = saveEmitLineAndColumnNumbers |
80 emitComputedPackingData = saveEmitComputedPackingData | 73 emitComputedPackingData = saveEmitComputedPackingData |
81 emitSerializedRuntimeTypeInfo = saveEmitSerializedRuntimeTypeInfo | 74 emitSerializedRuntimeTypeInfo = saveEmitSerializedRuntimeTypeInfo |
82 populateCompleteTypeSet = savePopulateCompleteTypeSet | |
83 return | 75 return |
84 } | 76 } |
85 | 77 |
86 // translateDescriptor translates from a mojom.MojomDescriptor (the pure Go | 78 // translateDescriptor translates from a mojom.MojomDescriptor (the pure Go |
87 // representation used by the parser) to a mojom_files.MojomFileGraph (the | 79 // representation used by the parser) to a mojom_files.MojomFileGraph (the |
88 // Mojo Go representation used for serialization.) | 80 // Mojo Go representation used for serialization.) |
89 func translateDescriptor(d *mojom.MojomDescriptor) *mojom_files.MojomFileGraph { | 81 func translateDescriptor(d *mojom.MojomDescriptor) *mojom_files.MojomFileGraph { |
90 fileGraph := mojom_files.MojomFileGraph{} | 82 fileGraph := mojom_files.MojomFileGraph{} |
91 | 83 |
92 // Add |resolved_types| field. | 84 // Add |resolved_types| field. |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 // If we are in a mode where canonical file names are no
t being resolved | 138 // If we are in a mode where canonical file names are no
t being resolved |
147 // then emit a null value for |imports| rather than an e
mpty array. | 139 // then emit a null value for |imports| rather than an e
mpty array. |
148 file.Imports = nil | 140 file.Imports = nil |
149 } | 141 } |
150 } | 142 } |
151 | 143 |
152 // We will populate a RuntimeTypeInfo structure and then serialize it an
d | 144 // We will populate a RuntimeTypeInfo structure and then serialize it an
d |
153 // the serialized bytes will form the |serialized_runtime_type_info| fie
ld | 145 // the serialized bytes will form the |serialized_runtime_type_info| fie
ld |
154 // of the MojomFile. | 146 // of the MojomFile. |
155 typeInfo := mojom_types.RuntimeTypeInfo{} | 147 typeInfo := mojom_types.RuntimeTypeInfo{} |
156 » typeInfo.ServicesByName = make(map[string]mojom_types.ServiceTypeInfo) | 148 » typeInfo.Services = make(map[string]string) |
157 typeInfo.TypeMap = make(map[string]mojom_types.UserDefinedType) | 149 typeInfo.TypeMap = make(map[string]mojom_types.UserDefinedType) |
158 | 150 |
159 // We populate the declared_mojom_objects field | 151 // We populate the declared_mojom_objects field |
160 // and simultaneously we populate typeInfo.TypeMap. | 152 // and simultaneously we populate typeInfo.TypeMap. |
161 | 153 |
162 // Interfaces | 154 // Interfaces |
163 if f.Interfaces != nil && len(f.Interfaces) > 0 { | 155 if f.Interfaces != nil && len(f.Interfaces) > 0 { |
164 file.DeclaredMojomObjects.Interfaces = new([]string) | 156 file.DeclaredMojomObjects.Interfaces = new([]string) |
165 for _, intrfc := range f.Interfaces { | 157 for _, intrfc := range f.Interfaces { |
166 typeKey := intrfc.TypeKey() | 158 typeKey := intrfc.TypeKey() |
167 *(file.DeclaredMojomObjects.Interfaces) = append(*(file.
DeclaredMojomObjects.Interfaces), typeKey) | 159 *(file.DeclaredMojomObjects.Interfaces) = append(*(file.
DeclaredMojomObjects.Interfaces), typeKey) |
168 | 160 |
169 » » » addServiceTypeInfo(intrfc, &typeInfo) | 161 » » » addServiceName(intrfc, &typeInfo) |
170 typeInfo.TypeMap[typeKey] = fileGraph.ResolvedTypes[type
Key] | 162 typeInfo.TypeMap[typeKey] = fileGraph.ResolvedTypes[type
Key] |
171 if intrfc.Enums != nil { | 163 if intrfc.Enums != nil { |
172 // Add embedded enums to typeInfo.TypeMap. | 164 // Add embedded enums to typeInfo.TypeMap. |
173 for _, enum := range intrfc.Enums { | 165 for _, enum := range intrfc.Enums { |
174 typeKey := enum.TypeKey() | 166 typeKey := enum.TypeKey() |
175 typeInfo.TypeMap[typeKey] = fileGraph.Re
solvedTypes[typeKey] | 167 typeInfo.TypeMap[typeKey] = fileGraph.Re
solvedTypes[typeKey] |
176 } | 168 } |
177 } | 169 } |
178 } | 170 } |
179 } | 171 } |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 panic(fmt.Sprintf("Error while gzipping runtimeTypeInfo:
%s", err.Error())) | 239 panic(fmt.Sprintf("Error while gzipping runtimeTypeInfo:
%s", err.Error())) |
248 } | 240 } |
249 byteSlice = compressedBytes.Bytes() | 241 byteSlice = compressedBytes.Bytes() |
250 encoded := base64.StdEncoding.EncodeToString(byteSlice) | 242 encoded := base64.StdEncoding.EncodeToString(byteSlice) |
251 file.SerializedRuntimeTypeInfo = &encoded | 243 file.SerializedRuntimeTypeInfo = &encoded |
252 } | 244 } |
253 | 245 |
254 return | 246 return |
255 } | 247 } |
256 | 248 |
257 // addServiceTypeInfo will add a ServiceTypeInfo to the ServicesByName field of
|typeInfo| corresponding | 249 // addServiceName will add the service name of |intrfc| to the |Services| field
of |typeInfo| |
258 // to |intrfc| if |intrfc| is a top-level interface, meaning that it has a non-n
il service name. In that | 250 // if |intrfc| is a top-level interface, meaning that it has a non-nil service n
ame. In that |
259 // case this method returns true. Otherwise this method will do nothing and retu
rn fals. | 251 // case this method returns true. Otherwise this method will do nothing and retu
rn fals. |
260 func addServiceTypeInfo(intrfc *mojom.MojomInterface, typeInfo *mojom_types.Runt
imeTypeInfo) (isTopLevel bool) { | 252 func addServiceName(intrfc *mojom.MojomInterface, typeInfo *mojom_types.RuntimeT
ypeInfo) (isTopLevel bool) { |
261 isTopLevel = intrfc.ServiceName != nil | 253 isTopLevel = intrfc.ServiceName != nil |
262 if isTopLevel { | 254 if isTopLevel { |
263 » » serviceTypeInfo := mojom_types.ServiceTypeInfo{} | 255 » » typeInfo.Services[*intrfc.ServiceName] = intrfc.TypeKey() |
264 » » serviceTypeInfo.TopLevelInterface = intrfc.TypeKey() | |
265 » » if populateCompleteTypeSet { | |
266 » » » serviceTypeInfo.CompleteTypeSet = intrfc.FindReachableTy
pes() | |
267 » » } | |
268 » » typeInfo.ServicesByName[*intrfc.ServiceName] = serviceTypeInfo | |
269 } | 256 } |
270 return | 257 return |
271 } | 258 } |
272 | 259 |
273 // translateUserDefinedType translates from a mojom.UserDefinedType (the pure Go | 260 // translateUserDefinedType translates from a mojom.UserDefinedType (the pure Go |
274 // representation used by the parser) to a mojom_types.UserDefinedType (the | 261 // representation used by the parser) to a mojom_types.UserDefinedType (the |
275 // Mojo Go representation used for serialization.) | 262 // Mojo Go representation used for serialization.) |
276 func translateUserDefinedType(t mojom.UserDefinedType) mojom_types.UserDefinedTy
pe { | 263 func translateUserDefinedType(t mojom.UserDefinedType) mojom_types.UserDefinedTy
pe { |
277 switch p := t.(type) { | 264 switch p := t.(type) { |
278 case *mojom.MojomStruct: | 265 case *mojom.MojomStruct: |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 | 722 |
736 // stringPointer is a convenience function for creating a pointer to a string wh
ose value | 723 // stringPointer is a convenience function for creating a pointer to a string wh
ose value |
737 // is the specified string. It may be used in situations where the compiler will | 724 // is the specified string. It may be used in situations where the compiler will |
738 // not allow you to take the address of a string value directly, such as the | 725 // not allow you to take the address of a string value directly, such as the |
739 // return value of a function. It is necessary to create pointers to strings bec
ause | 726 // return value of a function. It is necessary to create pointers to strings bec
ause |
740 // that is how the Mojom type |string?| (i.e. nullable string) is represented in | 727 // that is how the Mojom type |string?| (i.e. nullable string) is represented in |
741 // in the Mojom Go bindings. | 728 // in the Mojom Go bindings. |
742 func stringPointer(s string) *string { | 729 func stringPointer(s string) *string { |
743 return &s | 730 return &s |
744 } | 731 } |
OLD | NEW |