public SynchronizationEngine(ITemplateSignatureProvider signatureProvider, TemplateGenerationMetadata templateMetadata, ITypeListProvider typeListProvider, string configurationName)
 {
     _signatureProvider = signatureProvider;
     _templateMetadata = templateMetadata;
     _typeListProvider = typeListProvider;
     _configurationName = configurationName;
 }
        /// <summary>
        /// Generates source code files and writes them to disk
        /// </summary>
        public void Generate(TemplateGenerationMetadata metadata)
        {
            // this is a hack hack hack. Use parameters, lazybones.
            _metadata = metadata;
            _parameters = metadata.Parameters;

            // for source generation we want to split the generated code into separate units (files)
            CodeCompileUnit interfaceUnit = CreateCodeCompileUnit();
            CodeCompileUnit concreteUnit = CreateCodeCompileUnit();

            GenerateInterfaceCode(interfaceUnit);
            GenerateTemplateCode(concreteUnit);

            SortCodeCompileUnit(concreteUnit);
            SortCodeCompileUnit(interfaceUnit);

            WriteFileWithBackups(_parameters.ItemOutputPath, concreteUnit);
            WriteFileWithBackups(_parameters.InterfaceOutputPath, interfaceUnit);
        }
        /// <summary>
        /// Generates an interface for each template that the current template derives from, recursively.
        /// </summary>
        private TemplateInfo GenerateInheritedInterfaces(ITemplateInfo template, TemplateGenerationMetadata templateData)
        {
            var existingInterface = templateData.GetInterface(template.TemplateId);
            if (existingInterface != null) return existingInterface;

            var interfaceInfo = templateData.AddInterface(template, _parameters.InterfaceSuffix);

            var fieldKeys = GetBaseFieldSet();
            fieldKeys.Add(interfaceInfo.TypeName); // member names cannot be the same as their enclosing type
            fieldKeys.Add(template.Name.AsIdentifier()); // prevent any fields from being generated that would conflict with a concrete item name as well as the interface name

            // create interface properties
            foreach (var field in template.OwnFields)
            {
                if (_templateInputProvider.IsFieldIncluded(field.Id))
                {
                    string propertyName = field.Name.AsNovelIdentifier(fieldKeys);

                    var fieldInfo = new FieldPropertyInfo(field);
                    fieldInfo.FieldPropertyName = propertyName;
                    fieldInfo.SearchFieldName = _indexFieldNameTranslator.GetIndexFieldName(field.Name);
                    fieldInfo.FieldType = _fieldMappingProvider.GetFieldType(field);

                    if (fieldInfo.FieldType == null)
                    {
                        Log.Warn("Synthesis: Field type resolution for " + field.Template.Name + "::" + field.Name + " failed; no mapping found for field type " + field.Type, this);
                        continue; // skip adding the field for generation
                    }

                    // record usage of the property name
                    fieldKeys.Add(propertyName);

                    // add the field to the metadata
                    interfaceInfo.FieldsToGenerate.Add(fieldInfo);
                }
            }

            // add base interface inheritance
            foreach (var baseTemplate in template.BaseTemplates)
            {
                if (baseTemplate.Name.ToUpperInvariant() != StandardTemplate)
                {
                    // recursively generate base templates' interfaces as needed
                    var baseInterface = GenerateInheritedInterfaces(baseTemplate, templateData);
                    if (baseInterface != null)
                        interfaceInfo.InterfacesImplemented.Add(baseInterface); // assign interface implementation
                }
            }

            return interfaceInfo;
        }
        private TemplateGenerationMetadata CreateTemplateData()
        {
            var templates = _templateInputProvider.CreateTemplateList();

            var templateData = new TemplateGenerationMetadata(_parameters.UseTemplatePathForNamespace, _parameters.TemplatePathRoot, _parameters);

            foreach (var friendMetadata in _parameters.GetFriendMetadata())
            {
                foreach (var iface in friendMetadata.Interfaces)
                {
                    templateData.AddFriendInterface(iface);
                }
            }

            foreach (var template in templates) templateData.AddConcrete(template);
            return templateData;
        }
 /// <summary>
 /// Adds friend metadata (e.g. a template built in a different configuration) which can be referenced by templates in this one as a base
 /// </summary>
 public virtual void AddFriendMetadata(TemplateGenerationMetadata metadata)
 {
     Assert.ArgumentNotNull(metadata, "metadata");
     _friendMetadata.Add(metadata);
 }