blob: cf25fb714ce2853d368021775042e4c338ece7b9 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package serialization
import (
"bytes"
"compress/gzip"
"encoding/base64"
"fmt"
"mojo/public/go/bindings"
"mojom/mojom_tool/generated/mojom_files"
"mojom/mojom_tool/generated/mojom_types"
"mojom/mojom_tool/mojom"
myfmt "third_party/golang/src/fmt"
)
//////////////////////////////////////////////////
/// Mojom Descriptor Serialization
//////////////////////////////////////////////////
// This variable may be set to false in order to omit emitting line and
// column numbers. This is useful in tests.
var emitLineAndColumnNumbers bool = true
// This variable may be set to false in order to omit emitting computed
// packing. This is useful in tests.
var emitComputedPackingData bool = true
// This variable may be set to false in order to omit emitting serialized
// runtime type info. This is useful in tests.
var emitSerializedRuntimeTypeInfo bool = true
// Serialize serializes the MojomDescriptor into a binary form that is passed to the
// backend of the compiler in order to invoke the code generators.
// To do this we use Mojo serialization.
// If |debug| is true we also return a human-readable representation
// of the serialized mojom_types.FileGraph.
// This function is not thread safe.
func Serialize(d *mojom.MojomDescriptor, debug bool) (bytes []byte, debugString string, err error) {
return serialize(d, debug, true, true, true)
}
// serialize() is a package-private version of the public method Serialize().
// It is intended for use in tests because it allows setting of the variables
// emitLineAndColumnNumbers, emitComputedPackingData and emitSerializedRuntimeTypeInfo.
// This function is not thread safe because it sets and accesses these global
// variables.
func serialize(d *mojom.MojomDescriptor, debug,
emitLineAndColumnNumbersParam, emitComputedPackingDataParam,
emitSerializedRuntimeTypeInfoParam bool) (bytes []byte, debugString string, err error) {
// Save the global state and then set it based on the parameters.
saveEmitLineAndColumnNumbers := emitLineAndColumnNumbers
emitLineAndColumnNumbers = emitLineAndColumnNumbersParam
saveEmitComputedPackingData := emitComputedPackingData
emitComputedPackingData = emitComputedPackingDataParam
saveEmitSerializedRuntimeTypeInfo := emitSerializedRuntimeTypeInfo
emitSerializedRuntimeTypeInfo = emitSerializedRuntimeTypeInfoParam
fileGraph := translateDescriptor(d)
if debug {
debugString = myfmt.Sprintf("%#v", fileGraph)
}
encoder := bindings.NewEncoder()
encoder.SetDeterministic(true)
fileGraph.Encode(encoder)
bytes, _, err = encoder.Data()
// Restore the original values of the global state.
emitLineAndColumnNumbers = saveEmitLineAndColumnNumbers
emitComputedPackingData = saveEmitComputedPackingData
emitSerializedRuntimeTypeInfo = saveEmitSerializedRuntimeTypeInfo
return
}
// translateDescriptor translates from a mojom.MojomDescriptor (the pure Go
// representation used by the parser) to a mojom_files.MojomFileGraph (the
// Mojo Go representation used for serialization.)
func translateDescriptor(d *mojom.MojomDescriptor) *mojom_files.MojomFileGraph {
fileGraph := mojom_files.MojomFileGraph{}
// Add |resolved_types| field.
fileGraph.ResolvedTypes = make(map[string]mojom_types.UserDefinedType)
for key, userDefinedType := range d.TypesByKey {
fileGraph.ResolvedTypes[key] = translateUserDefinedType(userDefinedType)
}
// Add |resolved_values| field.
fileGraph.ResolvedValues = make(map[string]mojom_types.UserDefinedValue)
for key, userDefinedValue := range d.ValuesByKey {
fileGraph.ResolvedValues[key] = translateUserDefinedValue(userDefinedValue)
}
// Add |files| field.
fileGraph.Files = make(map[string]mojom_files.MojomFile)
for name, file := range d.MojomFilesByName {
fileGraph.Files[name] = translateMojomFile(file, &fileGraph)
}
return &fileGraph
}
// translateMojomFile translates from a mojom.MojomFile (the pure Go
// representation used by the parser) to a mojom_files.MojomFile (the
// Mojo Go representation used for serialization.)
func translateMojomFile(f *mojom.MojomFile, fileGraph *mojom_files.MojomFileGraph) (file mojom_files.MojomFile) {
// file_name field
file.FileName = f.CanonicalFileName
// specified_file_name_field
file.SpecifiedFileName = &f.SpecifiedFileName
// module_namespace field
file.ModuleNamespace = &f.ModuleNamespace.Identifier
// attributes field
if f.Attributes != nil {
file.Attributes = new([]mojom_types.Attribute)
for _, attr := range f.Attributes.List {
*(file.Attributes) = append(*(file.Attributes), translateMojomAttribute(&attr))
}
}
// imports field
if len(f.Imports) > 0 {
file.Imports = new([]string)
for _, importName := range f.Imports {
// We support serializing a MojomFileGraph that has not had import names
// resolved to canonical file names. (For example this is the case in
// meta-data-only mode.)
if importName.CanonicalFileName != "" {
*(file.Imports) = append(*(file.Imports), importName.CanonicalFileName)
}
}
if len(*file.Imports) == 0 {
// If we are in a mode where canonical file names are not being resolved
// then emit a null value for |imports| rather than an empty array.
file.Imports = nil
}
}
// We will populate a RuntimeTypeInfo structure and then serialize it and
// the serialized bytes will form the |serialized_runtime_type_info| field
// of the MojomFile.
typeInfo := mojom_types.RuntimeTypeInfo{}
typeInfo.Services = make(map[string]string)
typeInfo.TypeMap = make(map[string]mojom_types.UserDefinedType)
// We populate the declared_mojom_objects field
// and simultaneously we populate typeInfo.TypeMap.
// Interfaces
if f.Interfaces != nil && len(f.Interfaces) > 0 {
file.DeclaredMojomObjects.Interfaces = new([]string)
for _, intrfc := range f.Interfaces {
typeKey := intrfc.TypeKey()
*(file.DeclaredMojomObjects.Interfaces) = append(*(file.DeclaredMojomObjects.Interfaces), typeKey)
addServiceName(intrfc, &typeInfo)
typeInfo.TypeMap[typeKey] = fileGraph.ResolvedTypes[typeKey]
if intrfc.Enums != nil {
// Add embedded enums to typeInfo.TypeMap.
for _, enum := range intrfc.Enums {
typeKey := enum.TypeKey()
typeInfo.TypeMap[typeKey] = fileGraph.ResolvedTypes[typeKey]
}
}
}
}
// Structs
if f.Structs != nil && len(f.Structs) > 0 {
file.DeclaredMojomObjects.Structs = new([]string)
for _, strct := range f.Structs {
typeKey := strct.TypeKey()
*(file.DeclaredMojomObjects.Structs) = append(*(file.DeclaredMojomObjects.Structs), typeKey)
typeInfo.TypeMap[typeKey] = fileGraph.ResolvedTypes[typeKey]
if strct.Enums != nil {
// Add embedded enums to typeInfo.TypeMap.
for _, enum := range strct.Enums {
typeKey := enum.TypeKey()
typeInfo.TypeMap[typeKey] = fileGraph.ResolvedTypes[typeKey]
}
}
}
}
// Unions
if f.Unions != nil && len(f.Unions) > 0 {
file.DeclaredMojomObjects.Unions = new([]string)
for _, union := range f.Unions {
typeKey := union.TypeKey()
*(file.DeclaredMojomObjects.Unions) = append(*(file.DeclaredMojomObjects.Unions), typeKey)
typeInfo.TypeMap[typeKey] = fileGraph.ResolvedTypes[typeKey]
}
}
// TopLevelEnums
if f.Enums != nil && len(f.Enums) > 0 {
file.DeclaredMojomObjects.TopLevelEnums = new([]string)
for _, enum := range f.Enums {
typeKey := enum.TypeKey()
*(file.DeclaredMojomObjects.TopLevelEnums) = append(*(file.DeclaredMojomObjects.TopLevelEnums), typeKey)
typeInfo.TypeMap[typeKey] = fileGraph.ResolvedTypes[typeKey]
}
}
// TopLevelConstants
if f.Constants != nil && len(f.Constants) > 0 {
file.DeclaredMojomObjects.TopLevelConstants = new([]string)
for _, constant := range f.Constants {
*(file.DeclaredMojomObjects.TopLevelConstants) = append(*(file.DeclaredMojomObjects.TopLevelConstants), constant.ValueKey())
}
}
// TODO(rudominer) Do we need the EmbeddedEnums and EmbeddedConstants
// fields in KeysByType. It seems these fields are not currently being
// used in mojom_translator.py.
// SerializedRuntimeTypeInfo
if emitSerializedRuntimeTypeInfo {
encoder := bindings.NewEncoder()
encoder.SetDeterministic(true)
typeInfo.Encode(encoder)
byteSlice, _, err := encoder.Data()
if err != nil {
panic(fmt.Sprintf("Error while serializing runtimeTypeInfo: %s", err.Error()))
}
var compressedBytes bytes.Buffer
gzipWriter, _ := gzip.NewWriterLevel(&compressedBytes, gzip.BestCompression)
_, err = gzipWriter.Write(byteSlice)
if err != nil {
panic(fmt.Sprintf("Error while gzipping runtimeTypeInfo: %s", err.Error()))
}
err = gzipWriter.Close()
if err != nil {
panic(fmt.Sprintf("Error while gzipping runtimeTypeInfo: %s", err.Error()))
}
byteSlice = compressedBytes.Bytes()
encoded := base64.StdEncoding.EncodeToString(byteSlice)
file.SerializedRuntimeTypeInfo = &encoded
}
return
}
// addServiceName will add the service name of |intrfc| to the |Services| field of |typeInfo|
// if |intrfc| is a top-level interface, meaning that it has a non-nil service name. In that
// case this method returns true. Otherwise this method will do nothing and return fals.
func addServiceName(intrfc *mojom.MojomInterface, typeInfo *mojom_types.RuntimeTypeInfo) (isTopLevel bool) {
isTopLevel = intrfc.ServiceName != nil
if isTopLevel {
typeInfo.Services[*intrfc.ServiceName] = intrfc.TypeKey()
}
return
}
// translateUserDefinedType translates from a mojom.UserDefinedType (the pure Go
// representation used by the parser) to a mojom_types.UserDefinedType (the
// Mojo Go representation used for serialization.)
func translateUserDefinedType(t mojom.UserDefinedType) mojom_types.UserDefinedType {
switch p := t.(type) {
case *mojom.MojomStruct:
return &mojom_types.UserDefinedTypeStructType{translateMojomStruct(p)}
case *mojom.MojomInterface:
return translateMojomInterface(p)
case *mojom.MojomEnum:
return translateMojomEnum(p)
case *mojom.MojomUnion:
return translateMojomUnion(p)
default:
panic(fmt.Sprintf("Unexpected type: %T", t))
}
}
func translateMojomStruct(s *mojom.MojomStruct) mojom_types.MojomStruct {
mojomStruct := mojom_types.MojomStruct{}
mojomStruct.DeclData = translateDeclarationData(&s.DeclarationData)
mojomStruct.DeclData.ContainedDeclarations = translateContainedDeclarations(&s.NestedDeclarations)
for _, field := range s.FieldsInOrdinalOrder() {
mojomStruct.Fields = append(mojomStruct.Fields, translateStructField(field))
}
if emitComputedPackingData {
versionInfo := s.VersionInfo()
mojomStruct.VersionInfo = new([]mojom_types.StructVersion)
for _, version := range versionInfo {
(*mojomStruct.VersionInfo) = append(*mojomStruct.VersionInfo,
translateStructVersion(version))
}
}
return mojomStruct
}
func translateStructVersion(v mojom.StructVersion) mojom_types.StructVersion {
return mojom_types.StructVersion{
VersionNumber: v.VersionNumber,
NumFields: v.NumFields,
NumBytes: v.NumBytes,
}
}
func translateStructField(f *mojom.StructField) (field mojom_types.StructField) {
field.DeclData = translateDeclarationData(&f.DeclarationData)
field.Type = translateTypeRef(f.FieldType)
if f.DefaultValue != nil {
field.DefaultValue = translateDefaultFieldValue(f.DefaultValue)
}
if emitComputedPackingData {
// TODO(rudominer) Check the allowed size of offsets. The type used in
// mojom_types.mojom might need to be changed.
field.Offset = int32(f.Offset())
field.Bit = int8(f.Bit())
field.MinVersion = f.MinVersion()
}
return
}
func translateDefaultFieldValue(v mojom.ValueRef) mojom_types.DefaultFieldValue {
switch v := v.(type) {
case mojom.LiteralValue:
if v.IsDefault() {
return &mojom_types.DefaultFieldValueDefaultKeyword{mojom_types.DefaultKeyword{}}
}
return &mojom_types.DefaultFieldValueValue{translateLiteralValue(v)}
case *mojom.UserValueRef:
return &mojom_types.DefaultFieldValueValue{translateUserValueRef(v)}
default:
panic(fmt.Sprintf("Unexpected ValueRef type: %T", v))
}
}
func translateMojomInterface(intrfc *mojom.MojomInterface) *mojom_types.UserDefinedTypeInterfaceType {
mojomInterface := mojom_types.UserDefinedTypeInterfaceType{}
mojomInterface.Value.DeclData = translateDeclarationData(&intrfc.DeclarationData)
mojomInterface.Value.DeclData.ContainedDeclarations = translateContainedDeclarations(&intrfc.NestedDeclarations)
mojomInterface.Value.ServiceName = intrfc.ServiceName
mojomInterface.Value.Methods = make(map[uint32]mojom_types.MojomMethod)
for ordinal, method := range intrfc.MethodsByOrdinal {
mojomInterface.Value.Methods[ordinal] = translateMojomMethod(method)
}
if emitComputedPackingData {
mojomInterface.Value.CurrentVersion = intrfc.Version()
}
return &mojomInterface
}
func translateMojomMethod(method *mojom.MojomMethod) mojom_types.MojomMethod {
mojomMethod := mojom_types.MojomMethod{}
// decl_data
mojomMethod.DeclData = translateDeclarationData(&method.DeclarationData)
// parameters
mojomMethod.Parameters = translateMojomStruct(method.Parameters)
// response_params
if method.ResponseParameters != nil {
responseParams := translateMojomStruct(method.ResponseParameters)
mojomMethod.ResponseParams = &responseParams
}
// ordinal
mojomMethod.Ordinal = method.Ordinal
if emitComputedPackingData {
mojomMethod.MinVersion = method.MinVersion()
}
return mojomMethod
}
func translateMojomEnum(enum *mojom.MojomEnum) *mojom_types.UserDefinedTypeEnumType {
mojomEnum := mojom_types.UserDefinedTypeEnumType{}
mojomEnum.Value.DeclData = translateDeclarationData(&enum.DeclarationData)
for _, value := range enum.Values {
mojomEnum.Value.Values = append(mojomEnum.Value.Values, translateEnumValue(value))
}
return &mojomEnum
}
func translateMojomUnion(union *mojom.MojomUnion) *mojom_types.UserDefinedTypeUnionType {
mojomUnion := mojom_types.UserDefinedTypeUnionType{}
mojomUnion.Value.DeclData = translateDeclarationData(&union.DeclarationData)
for _, field := range union.FieldsInTagOrder() {
mojomUnion.Value.Fields = append(mojomUnion.Value.Fields,
translateUnionField(field))
}
return &mojomUnion
}
func translateUnionField(unionField *mojom.UnionField) mojom_types.UnionField {
outUnionField := mojom_types.UnionField{}
outUnionField.DeclData = translateDeclarationData(&unionField.DeclarationData)
outUnionField.Type = translateTypeRef(unionField.FieldType)
outUnionField.Tag = unionField.Tag
return outUnionField
}
// WARNING: Do not invoke this function on a UserDefinedValue of type BuiltInConstantValue because
// objects of those types do not have a type_key and do not correspond to a mojom_types.UserDefinedValue.
func translateUserDefinedValue(v mojom.UserDefinedValue) mojom_types.UserDefinedValue {
switch t := v.(type) {
case *mojom.UserDefinedConstant:
return translateUserDefinedConstant(t)
case *mojom.EnumValue:
return &mojom_types.UserDefinedValueEnumValue{translateEnumValue(t)}
case *mojom.BuiltInConstantValue:
panic("Do not invoke translateUserDefinedValue on BuiltInConstantValue.")
default:
panic(fmt.Sprintf("Unexpected UserDefinedValue type %T", v))
}
}
func translateUserDefinedConstant(t *mojom.UserDefinedConstant) *mojom_types.UserDefinedValueDeclaredConstant {
declaredConstant := mojom_types.UserDefinedValueDeclaredConstant{}
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()))
return &declaredConstant
}
func translateEnumValue(v *mojom.EnumValue) mojom_types.EnumValue {
enumValue := mojom_types.EnumValue{}
enumValue.DeclData = translateDeclarationData(&v.DeclarationData)
enumValue.EnumTypeKey = v.EnumType().TypeKey()
if v.ValueRef() != nil {
enumValue.InitializerValue = translateValueRef(v.ValueRef())
}
if !v.IntValueComputed {
panic(fmt.Sprintf("IntValueComputed is false for %v.", v))
}
enumValue.IntValue = v.ComputedIntValue
return enumValue
}
func translateTypeRef(typeRef mojom.TypeRef) mojom_types.Type {
switch t := typeRef.(type) {
case mojom.SimpleType:
return translateSimpleType(t)
case mojom.StringType:
return translateStringType(t)
case mojom.HandleTypeRef:
return translateHandleType(t)
case mojom.ArrayTypeRef:
return translateArrayType(&t)
case *mojom.ArrayTypeRef:
return translateArrayType(t)
case mojom.MapTypeRef:
return translateMapType(&t)
case *mojom.MapTypeRef:
return translateMapType(t)
case *mojom.UserTypeRef:
return translateUserTypeRef(t)
default:
panic(fmt.Sprintf("Unexpected TypeRef type %T", t))
}
}
func translateSimpleType(simpleType mojom.SimpleType) *mojom_types.TypeSimpleType {
var value mojom_types.SimpleType
switch simpleType {
case mojom.SimpleTypeBool:
value = mojom_types.SimpleType_Bool
case mojom.SimpleTypeDouble:
value = mojom_types.SimpleType_Double
case mojom.SimpleTypeFloat:
value = mojom_types.SimpleType_Float
case mojom.SimpleTypeInt8:
value = mojom_types.SimpleType_Int8
case mojom.SimpleTypeInt16:
value = mojom_types.SimpleType_Int16
case mojom.SimpleTypeInt32:
value = mojom_types.SimpleType_Int32
case mojom.SimpleTypeInt64:
value = mojom_types.SimpleType_Int64
case mojom.SimpleTypeUInt8:
value = mojom_types.SimpleType_Uint8
case mojom.SimpleTypeUInt16:
value = mojom_types.SimpleType_Uint16
case mojom.SimpleTypeUInt32:
value = mojom_types.SimpleType_Uint32
case mojom.SimpleTypeUInt64:
value = mojom_types.SimpleType_Uint64
}
return &mojom_types.TypeSimpleType{value}
}
func translateStringType(stringType mojom.StringType) *mojom_types.TypeStringType {
return &mojom_types.TypeStringType{mojom_types.StringType{stringType.Nullable()}}
}
func translateHandleType(handleType mojom.HandleTypeRef) *mojom_types.TypeHandleType {
var kind mojom_types.HandleType_Kind
switch handleType.HandleKind() {
case mojom.HandleKindUnspecified:
kind = mojom_types.HandleType_Kind_Unspecified
case mojom.HandleKindMessagePipe:
kind = mojom_types.HandleType_Kind_MessagePipe
case mojom.HandleKindDataPipeConsumer:
kind = mojom_types.HandleType_Kind_DataPipeConsumer
case mojom.HandleKindDataPipeProducer:
kind = mojom_types.HandleType_Kind_DataPipeProducer
case mojom.HandleKindSharedBuffer:
kind = mojom_types.HandleType_Kind_SharedBuffer
}
return &mojom_types.TypeHandleType{mojom_types.HandleType{handleType.Nullable(), kind}}
}
func translateArrayType(arrayType *mojom.ArrayTypeRef) *mojom_types.TypeArrayType {
return &mojom_types.TypeArrayType{mojom_types.ArrayType{
Nullable: arrayType.Nullable(),
FixedLength: int32(arrayType.FixedLength()),
ElementType: translateTypeRef(arrayType.ElementType())}}
}
func translateMapType(mapType *mojom.MapTypeRef) *mojom_types.TypeMapType {
return &mojom_types.TypeMapType{mojom_types.MapType{
Nullable: mapType.Nullable(),
KeyType: translateTypeRef(mapType.KeyType()),
ValueType: translateTypeRef(mapType.ValueType())}}
}
func translateUserTypeRef(userType *mojom.UserTypeRef) *mojom_types.TypeTypeReference {
typeKey := stringPointer(userType.ResolvedType().TypeKey())
identifier := stringPointer(userType.Identifier())
return &mojom_types.TypeTypeReference{mojom_types.TypeReference{
Nullable: userType.Nullable(),
IsInterfaceRequest: userType.IsInterfaceRequest(),
Identifier: identifier,
TypeKey: typeKey}}
}
func translateValueRef(valueRef mojom.ValueRef) mojom_types.Value {
switch valueRef := valueRef.(type) {
case mojom.LiteralValue:
return translateLiteralValue(valueRef)
case *mojom.UserValueRef:
return translateUserValueRef(valueRef)
default:
panic(fmt.Sprintf("Unexpected ValueRef type %T", valueRef))
}
}
func translateLiteralValue(v mojom.LiteralValue) *mojom_types.ValueLiteralValue {
var lv mojom_types.LiteralValue
switch v.ValueType() {
case mojom.SimpleTypeBool:
lv = &mojom_types.LiteralValueBoolValue{v.Value().(bool)}
case mojom.SimpleTypeDouble:
lv = &mojom_types.LiteralValueDoubleValue{v.Value().(float64)}
case mojom.SimpleTypeFloat:
lv = &mojom_types.LiteralValueFloatValue{v.Value().(float32)}
case mojom.SimpleTypeInt8:
lv = &mojom_types.LiteralValueInt8Value{v.Value().(int8)}
case mojom.SimpleTypeInt16:
lv = &mojom_types.LiteralValueInt16Value{v.Value().(int16)}
case mojom.SimpleTypeInt32:
lv = &mojom_types.LiteralValueInt32Value{v.Value().(int32)}
case mojom.SimpleTypeInt64:
lv = &mojom_types.LiteralValueInt64Value{v.Value().(int64)}
case mojom.SimpleTypeUInt8:
lv = &mojom_types.LiteralValueUint8Value{v.Value().(uint8)}
case mojom.SimpleTypeUInt16:
lv = &mojom_types.LiteralValueUint16Value{v.Value().(uint16)}
case mojom.SimpleTypeUInt32:
lv = &mojom_types.LiteralValueUint32Value{v.Value().(uint32)}
case mojom.SimpleTypeUInt64:
lv = &mojom_types.LiteralValueUint64Value{v.Value().(uint64)}
case mojom.StringLiteralType:
lv = &mojom_types.LiteralValueStringValue{v.Value().(string)}
default:
panic(fmt.Sprintf("Unexpected literal value type %d", v.ValueType()))
}
return &mojom_types.ValueLiteralValue{lv}
}
func translateBuiltInConstantValue(t mojom.BuiltInConstantValue) *mojom_types.ValueBuiltinValue {
builtInValue := mojom_types.ValueBuiltinValue{}
switch t {
case mojom.FloatInfinity:
builtInValue.Value = mojom_types.BuiltinConstantValue_FloatInfinity
case mojom.FloatNegativeInfinity:
builtInValue.Value = mojom_types.BuiltinConstantValue_FloatNegativeInfinity
case mojom.FloatNAN:
builtInValue.Value = mojom_types.BuiltinConstantValue_FloatNan
case mojom.DoubleInfinity:
builtInValue.Value = mojom_types.BuiltinConstantValue_DoubleInfinity
case mojom.DoubleNegativeInfinity:
builtInValue.Value = mojom_types.BuiltinConstantValue_DoubleNegativeInfinity
case mojom.DoubleNAN:
builtInValue.Value = mojom_types.BuiltinConstantValue_DoubleNan
default:
panic(fmt.Sprintf("Unrecognized BuiltInConstantValue %v", t))
}
return &builtInValue
}
func translateUserValueRef(r *mojom.UserValueRef) mojom_types.Value {
switch t := r.ResolvedConcreteValue().(type) {
case mojom.BuiltInConstantValue:
return translateBuiltInConstantValue(t)
default:
valueKey := stringPointer(r.ResolvedDeclaredValue().ValueKey())
return &mojom_types.ValueUserValueReference{mojom_types.UserValueReference{
Identifier: r.Identifier(),
ValueKey: valueKey}}
}
}
func translateDeclarationData(d *mojom.DeclarationData) *mojom_types.DeclarationData {
declData := mojom_types.DeclarationData{}
// attributes field
if d.Attributes() != nil {
declData.Attributes = new([]mojom_types.Attribute)
for _, attr := range d.Attributes().List {
*(declData.Attributes) = append(*(declData.Attributes), translateMojomAttribute(&attr))
}
}
// min_version field
// TODO(rudominer) Eliminate the min_version field from struct DeclarationData
// short_name field
declData.ShortName = stringPointer(d.SimpleName())
// full_identifier field
switch declaredObject := d.DeclaredObject().(type) {
// We do not serialize the fully-qualified-name for objects that only exist
// as children of their container objects and are not independently
// referenceable.
case *mojom.StructField, *mojom.MojomMethod, *mojom.UnionField:
case *mojom.MojomStruct:
switch declaredObject.StructType() {
case mojom.StructTypeRegular:
declData.FullIdentifier = stringPointer(d.FullyQualifiedName())
}
default:
declData.FullIdentifier = stringPointer(d.FullyQualifiedName())
}
// declared_ordinal field
if d.DeclaredOrdinal() < 0 {
declData.DeclaredOrdinal = -1
} else {
declData.DeclaredOrdinal = int32(d.DeclaredOrdinal())
}
// declaration_order
if d.LexicalPosition() < 0 {
declData.DeclarationOrder = -1
} else {
declData.DeclarationOrder = d.LexicalPosition()
}
// container_type_key
containingType := d.ContainingType()
if containingType != nil {
switch d.DeclaredObject().(type) {
// We do not serialize the |container_type_key| field for objects that only exist
// as children of their container objects and are not independently
// referenceable.
case *mojom.StructField, *mojom.MojomMethod:
// We do not serialize the |container_type_key| field for an EnumValue
// because the EnumValue already has the type_key of the Enum
// in a different field.
case *mojom.EnumValue:
default:
declData.ContainerTypeKey = stringPointer(containingType.TypeKey())
}
}
// source_file_info
declData.SourceFileInfo = new(mojom_types.SourceFileInfo)
declData.SourceFileInfo.FileName = d.OwningFile().CanonicalFileName
if emitLineAndColumnNumbers {
declData.SourceFileInfo.LineNumber = d.LineNumber()
declData.SourceFileInfo.ColumnNumber = d.ColumnNumber()
}
return &declData
}
// Returns nil if there are no contained declarations
func translateContainedDeclarations(container *mojom.NestedDeclarations) *mojom_types.ContainedDeclarations {
if container.Enums == nil && container.Constants == nil {
return nil
}
declarations := mojom_types.ContainedDeclarations{}
if container.Enums != nil {
declarations.Enums = new([]string)
for _, enum := range container.Enums {
*declarations.Enums = append(*declarations.Enums, enum.TypeKey())
}
}
if container.Constants != nil {
declarations.Constants = new([]string)
for _, constant := range container.Constants {
*declarations.Constants = append(*declarations.Constants, constant.ValueKey())
}
}
return &declarations
}
func translateMojomAttribute(a *mojom.MojomAttribute) (attribute mojom_types.Attribute) {
return mojom_types.Attribute{a.Key, translateLiteralValue(a.Value).Value}
}
// stringPointer is a convenience function for creating a pointer to a string whose value
// is the specified string. It may be used in situations where the compiler will
// not allow you to take the address of a string value directly, such as the
// return value of a function. It is necessary to create pointers to strings because
// that is how the Mojom type |string?| (i.e. nullable string) is represented in
// in the Mojom Go bindings.
func stringPointer(s string) *string {
return &s
}