summaryrefslogtreecommitdiff
path: root/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FTypeCollectionGenerator.xtend
blob: af7f2860c008836db1c8eecce2ee9cb596acd94d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/* Copyright (C) 2013 BMW Group
 * Author: Manfred Bathelt (manfred.bathelt@bmw.de)
 * Author: Juergen Gehring (juergen.gehring@bmw.de)
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.genivi.commonapi.core.generator

import javax.inject.Inject
import org.eclipse.xtext.generator.IFileSystemAccess
import org.franca.core.franca.FStructType
import org.franca.core.franca.FTypeCollection
import org.genivi.commonapi.core.deployment.DeploymentInterfacePropertyAccessor
import java.util.HashSet
import java.util.Collection
import org.eclipse.core.resources.IResource

class FTypeCollectionGenerator {
    @Inject private extension FTypeGenerator
    @Inject private extension FTypeCommonAreaGenerator
    @Inject private extension FrancaGeneratorExtensions

    def generate(FTypeCollection fTypeCollection,
                 IFileSystemAccess fileSystemAccess,
                 DeploymentInterfacePropertyAccessor deploymentAccessor,
                 IResource modelid) {

        fileSystemAccess.generateFile(fTypeCollection.headerPath, fTypeCollection.generateHeader(deploymentAccessor, modelid))

        if (fTypeCollection.hasSourceFile) {
            fileSystemAccess.generateFile(fTypeCollection.sourcePath, fTypeCollection.generateSource(modelid))
        }
    }

    def private generateHeader(FTypeCollection fTypeCollection, DeploymentInterfacePropertyAccessor deploymentAccessor, IResource modelid) '''
        «generateCommonApiLicenseHeader(fTypeCollection, modelid)»
        «FTypeGenerator::generateComments(fTypeCollection, false)»
        #ifndef «fTypeCollection.defineName»_H_
        #define «fTypeCollection.defineName»_H_

        «val libraryHeaders = new HashSet<String>»
        «val generatedHeaders = new HashSet<String>»
        «fTypeCollection.getRequiredHeaderFiles(generatedHeaders, libraryHeaders)»

        «FOR requiredHeaderFile : generatedHeaders.sort»
            #include <«requiredHeaderFile»>
        «ENDFOR»

        #if !defined (COMMONAPI_INTERNAL_COMPILATION)
        #define COMMONAPI_INTERNAL_COMPILATION
        #endif

        «FOR requiredHeaderFile : libraryHeaders.sort»
            #include <«requiredHeaderFile»>
        «ENDFOR»

        #undef COMMONAPI_INTERNAL_COMPILATION

        «fTypeCollection.model.generateNamespaceBeginDeclaration»

        namespace «fTypeCollection.elementName» {
            «fTypeCollection.generateFTypeDeclarations(deploymentAccessor)»

        «FOR type : fTypeCollection.types»
            «type.generateFTypeInlineImplementation(type, deploymentAccessor)»
        «ENDFOR»


        static inline const char* getTypeCollectionName() {
            static const char* typeCollectionName = "«fTypeCollection.fullyQualifiedName»";
            return typeCollectionName;
        }

        «IF fTypeCollection.version != null»
            inline CommonAPI::Version getTypeCollectionVersion() {
                return CommonAPI::Version(«fTypeCollection.version.major», «fTypeCollection.version.minor»);
            }
        «ENDIF»

        } // namespace «fTypeCollection.elementName»

        «fTypeCollection.model.generateNamespaceEndDeclaration»

        namespace CommonAPI {

            «fTypeCollection.generateTypeWriters(deploymentAccessor)»

            «fTypeCollection.generateVariantComparators»
        }


        namespace std {
            «fTypeCollection.generateHashers(deploymentAccessor)»
        }

        #endif // «fTypeCollection.defineName»_H_
    '''

    def private generateSource(FTypeCollection fTypeCollection, IResource modelid) '''
        «generateCommonApiLicenseHeader(fTypeCollection, modelid)»
        «FTypeGenerator::generateComments(fTypeCollection, false)»
        #include "«fTypeCollection.headerFile»"

        «FOR fStructTypeHeaderPath : fTypeCollection.allDerivedFStructTypeHeaderPaths»
            #include <«fStructTypeHeaderPath»>
        «ENDFOR»

        «fTypeCollection.model.generateNamespaceBeginDeclaration»
        namespace «fTypeCollection.elementName» {

        «FOR type : fTypeCollection.types»
            «/*FTypeGenerator::generateComments(type.comment, false)*/»
            «type.generateFTypeImplementation(type)»
        «ENDFOR»

        } // namespace «fTypeCollection.elementName»
        «fTypeCollection.model.generateNamespaceEndDeclaration»
    '''

    def void getRequiredHeaderFiles(FTypeCollection fInterface, Collection<String> generatedHeaders,
        Collection<String> libraryHeaders) {
        libraryHeaders.add('CommonAPI/types.h')
        fInterface.types.forEach[addRequiredHeaders(generatedHeaders, libraryHeaders)]
        generatedHeaders.remove(fInterface.headerPath)
    }

    def private hasSourceFile(FTypeCollection fTypeCollection) {
        val hasTypeWithImplementation = fTypeCollection.types.exists[hasImplementation]
        return hasTypeWithImplementation
    }

    def private getAllDerivedFStructTypeHeaderPaths(FTypeCollection fTypeCollection) {
        return fTypeCollection.types.filter[it instanceof FStructType && (it as FStructType).hasPolymorphicBase].map[
            (it as FStructType).derivedFStructTypes].flatten.map[(eContainer as FTypeCollection).headerPath].toSet.filter[
            !fTypeCollection.headerPath.equals(it)]
    }
}