<commit_before>/**
 * Copyright (c) 2019 committers of YAKINDU and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     committers of YAKINDU - initial API and implementation
 */
package org.yakindu.sct.generator.cpp.submodules

import com.google.inject.Inject
import org.yakindu.base.types.Declaration
import org.yakindu.base.types.Direction
import org.yakindu.sct.generator.c.extensions.ExpressionsChecker
import org.yakindu.sct.generator.core.types.ICodegenTypeSystemAccess
import org.yakindu.sct.generator.cpp.CppNaming
import org.yakindu.sct.generator.cpp.features.GenmodelEntriesExtension
import org.yakindu.sct.generator.cpp.templates.ClassDeclaration
import org.yakindu.sct.model.sexec.ExecutionFlow
import org.yakindu.sct.model.sexec.extensions.SExecExtensions
import org.yakindu.sct.model.sgen.GeneratorEntry
import org.yakindu.sct.model.sgraph.Scope
import org.yakindu.sct.model.stext.stext.EventDefinition
import org.yakindu.sct.model.stext.stext.InterfaceScope
import org.yakindu.sct.model.stext.stext.InternalScope
import org.yakindu.sct.model.stext.stext.StatechartScope
import org.yakindu.sct.model.stext.stext.VariableDefinition

import static org.yakindu.sct.generator.c.CGeneratorConstants.*

class InterfaceFunctions {
	@Inject protected extension CppNaming
	@Inject protected extension SExecExtensions
	@Inject protected extension GenmodelEntriesExtension
	@Inject protected extension ICodegenTypeSystemAccess
	@Inject protected extension EventCode
	@Inject protected extension ExpressionsChecker
	
	@Inject protected GeneratorEntry entry
	
	def interfaceFunctions(ExecutionFlow it) '''
		«FOR scope : statechartScopes»
			«IF scope instanceof InterfaceScope»
			«module»::«scope.interfaceName»* «module»::get«scope.interfaceName»()
			{
				return &«scope.instance»;
			}
			«ENDIF»
			«generateEvents(scope)»
			«generateVariables(scope)»
			«IF scope.hasOperations && !entry.useStaticOPC»
				«scope.OCB_InterfaceSetterDeclaration(true)»
				{
					«scope.OCB_Instance» = operationCallback;
				}
			«ENDIF»
		«ENDFOR»
		«IF entry.tracingUsed»
		
		void «module»::set«traceObserverModule»(«YSCNamespace»::«traceObserverModule»<«statesEnumType»>* tracingcallback) {
			«tracingInstance» = tracingcallback;
		}
		
		«YSCNamespace»::«traceObserverModule»<«module»::«statesEnumType»>* «module»::get«traceObserverModule»() {
			return «tracingInstance»;
		}
		«ENDIF»
	'''
	
	def generateVariables(ExecutionFlow it, StatechartScope scope)
		'''
			«FOR variable : scope.variableDefinitions»
				«IF variable.isConstString»const «ENDIF»«variable.typeSpecifier.targetLanguageName» «module»::«scope.interfaceName»::«variable.asGetter»() const
				{
					return «variable.localAccess»;
				}
				
				«IF scope.defaultInterface»
					«IF variable.isConstString»const «ENDIF»«variable.typeSpecifier.targetLanguageName» «module»::«variable.asGetter»() const
					{
						return «variable.access»;
					}
					
				«ENDIF»
				«IF !variable.readonly && !variable.const»
					void «module»::«scope.interfaceName»::«variable.asSetter»(«variable.typeSpecifier.targetLanguageName» value)
					{
						«variable.localAccess» = value;
					}
					
					«IF scope.defaultInterface»
						void «module»::«variable.asSetter»(«variable.typeSpecifier.targetLanguageName» value)
						{
							«variable.access» = value;
						}
						
					«ENDIF»
				«ENDIF»
			«ENDFOR»
		'''
		
	def createPublicScope(Scope scope) {
		switch scope {
			InterfaceScope: scope.createPublicScope
			InternalScope: scope.createPublicScope
		}
	}

	def createPublicScope(InterfaceScope scope) '''
		«scope.createInterface(new ClassDeclaration).generate»
		«««		«scope.createListenerInterface(entry)»
		«scope.createOCBInterface»
		
		/*! Returns an instance of the interface class '«scope.interfaceName»'. */
		«scope.interfaceName»* get«scope.interfaceName»();
		
		«IF scope.defaultInterface»
			«FOR d : scope.declarations»
				«d.functionPrototypes»
			«ENDFOR»
		«ENDIF»
	'''

	def createPublicScope(InternalScope scope) {
		scope.createOCBInterface
	}

	def createInterface(StatechartScope scope, ClassDeclaration scopeDecl) {
		scopeDecl
			.name(scope.interfaceName)
			.comment("//! Inner class for «scope.simpleName» interface scope.")
		
		scope.declarations.map[functionPrototypes].forEach[scopeDecl.publicMember(it)]
		scopeDecl.member(entry.innerClassVisibility, protectedInnerClassMembers(scope))
	}
	
	def CharSequence protectedInnerClassMembers(StatechartScope scope)
		'''
		friend class «scope.flow.module»;
		«FOR d : scope.declarations»
			«d.privateFunctionPrototypes»
			«d.scopeTypeDeclMember»
		«ENDFOR»
	'''
	

	def dispatch privateFunctionPrototypes(Declaration it) {
		''''''	
	}
	
	def dispatch privateFunctionPrototypes(EventDefinition it) {
		''''''	
	}
	
	def createOCBInterface(StatechartScope scope) {
		val scopeDecl = new ClassDeclaration<commit_msg>Fix comment of interface scope class (#2606)<commit_after>/**
 * Copyright (c) 2019 committers of YAKINDU and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     committers of YAKINDU - initial API and implementation
 */
package org.yakindu.sct.generator.cpp.submodules

import com.google.inject.Inject
import org.yakindu.base.types.Declaration
import org.yakindu.base.types.Direction
import org.yakindu.sct.generator.c.extensions.ExpressionsChecker
import org.yakindu.sct.generator.core.types.ICodegenTypeSystemAccess
import org.yakindu.sct.generator.cpp.CppNaming
import org.yakindu.sct.generator.cpp.features.GenmodelEntriesExtension
import org.yakindu.sct.generator.cpp.templates.ClassDeclaration
import org.yakindu.sct.model.sexec.ExecutionFlow
import org.yakindu.sct.model.sexec.extensions.SExecExtensions
import org.yakindu.sct.model.sgen.GeneratorEntry
import org.yakindu.sct.model.sgraph.Scope
import org.yakindu.sct.model.stext.stext.EventDefinition
import org.yakindu.sct.model.stext.stext.InterfaceScope
import org.yakindu.sct.model.stext.stext.InternalScope
import org.yakindu.sct.model.stext.stext.StatechartScope
import org.yakindu.sct.model.stext.stext.VariableDefinition

import static org.yakindu.sct.generator.c.CGeneratorConstants.*

class InterfaceFunctions {
	@Inject protected extension CppNaming
	@Inject protected extension SExecExtensions
	@Inject protected extension GenmodelEntriesExtension
	@Inject protected extension ICodegenTypeSystemAccess
	@Inject protected extension EventCode
	@Inject protected extension ExpressionsChecker
	
	@Inject protected GeneratorEntry entry
	
	def interfaceFunctions(ExecutionFlow it) '''
		«FOR scope : statechartScopes»
			«IF scope instanceof InterfaceScope»
			«module»::«scope.interfaceName»* «module»::get«scope.interfaceName»()
			{
				return &«scope.instance»;
			}
			«ENDIF»
			«generateEvents(scope)»
			«generateVariables(scope)»
			«IF scope.hasOperations && !entry.useStaticOPC»
				«scope.OCB_InterfaceSetterDeclaration(true)»
				{
					«scope.OCB_Instance» = operationCallback;
				}
			«ENDIF»
		«ENDFOR»
		«IF entry.tracingUsed»
		
		void «module»::set«traceObserverModule»(«YSCNamespace»::«traceObserverModule»<«statesEnumType»>* tracingcallback) {
			«tracingInstance» = tracingcallback;
		}
		
		«YSCNamespace»::«traceObserverModule»<«module»::«statesEnumType»>* «module»::get«traceObserverModule»() {
			return «tracingInstance»;
		}
		«ENDIF»
	'''
	
	def generateVariables(ExecutionFlow it, StatechartScope scope)
		'''
			«FOR variable : scope.variableDefinitions»
				«IF variable.isConstString»const «ENDIF»«variable.typeSpecifier.targetLanguageName» «module»::«scope.interfaceName»::«variable.asGetter»() const
				{
					return «variable.localAccess»;
				}
				
				«IF scope.defaultInterface»
					«IF variable.isConstString»const «ENDIF»«variable.typeSpecifier.targetLanguageName» «module»::«variable.asGetter»() const
					{
						return «variable.access»;
					}
					
				«ENDIF»
				«IF !variable.readonly && !variable.const»
					void «module»::«scope.interfaceName»::«variable.asSetter»(«variable.typeSpecifier.targetLanguageName» value)
					{
						«variable.localAccess» = value;
					}
					
					«IF scope.defaultInterface»
						void «module»::«variable.asSetter»(«variable.typeSpecifier.targetLanguageName» value)
						{
							«variable.access» = value;
						}
						
					«ENDIF»
				«ENDIF»
			«ENDFOR»
		'''
		
	def createPublicScope(Scope scope) {
		switch scope {
			InterfaceScope: scope.createPublicScope
			InternalScope: scope.createPublicScope
		}
	}

	def createPublicScope(InterfaceScope scope) '''
		«scope.createInterface(new ClassDeclaration).generate»
		«««		«scope.createListenerInterface(entry)»
		«scope.createOCBInterface»
		
		/*! Returns an instance of the interface class '«scope.interfaceName»'. */
		«scope.interfaceName»* get«scope.interfaceName»();
		
		«IF scope.defaultInterface»
			«FOR d : scope.declarations»
				«d.functionPrototypes»
			«ENDFOR»
		«ENDIF»
	'''

	def createPublicScope(InternalScope scope) {
		scope.createOCBInterface
	}

	def createInterface(StatechartScope scope, ClassDeclaration scopeDecl) {
		scopeDecl
			.name(scope.interfaceName)
			.comment('''//! Inner class for «scope.simpleName» interface scope.''')
		
		scope.declarations.map[functionPrototypes].forEach[scopeDecl.publicMember(it)]
		scopeDecl.member(entry.innerClassVisibility, protectedInnerClassMembers(scope))
	}
	
	def CharSequence protectedInnerClassMembers(StatechartScope scope)
		'''
		friend class «scope.flow.module»;
		«FOR d : scope.declarations»
			«d.privateFunctionPrototypes»
			«d.scopeTypeDeclMember»
		«ENDFOR»
	'''
	

	def dispatch privateFunctionPrototypes(Declaration it) {
		''''''	
	}
	
	def dispatch privateFunctionPrototypes(EventDefinition it) {
		''''''	
	}
	
	def createOCBInterface(StatechartScope scope) {
		val scopeDecl = new ClassDeclaration
{'fraction_non_alphanumeric': 0.11156741957563313, 'fraction_numerical': 0.001955607705094358, 'mean_word_length': 4.742841100505334, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4633186', 'n_tokens_mistral': 3682, 'n_tokens_neox': 3178, 'n_words': 929}