/// <summary> /// Generate NodeJS client code /// </summary> /// <param name="serviceClient"></param> /// <returns></returns> public override async Task Generate(CodeModel cm) { var disableTypeScriptGeneration = Singleton<GeneratorSettingsJs>.Instance.DisableTypeScriptGeneration; var codeModel = cm as CodeModelJs; if (codeModel == null) { throw new InvalidCastException("CodeModel is not a NodeJS code model."); } // Service client var serviceClientTemplate = new ServiceClientTemplate {Model = codeModel}; await Write(serviceClientTemplate, codeModel.Name.ToCamelCase() + ".js"); if (!disableTypeScriptGeneration) { var serviceClientTemplateTS = new ServiceClientTemplateTS {Model = codeModel}; await Write(serviceClientTemplateTS, codeModel.Name.ToCamelCase() + ".d.ts"); } //Models if (codeModel.ModelTypes.Any()) { var modelIndexTemplate = new ModelIndexTemplate {Model = codeModel}; await Write(modelIndexTemplate, Path.Combine("models", "index.js")); if (!disableTypeScriptGeneration) { var modelIndexTemplateTS = new ModelIndexTemplateTS {Model = codeModel}; await Write(modelIndexTemplateTS, Path.Combine("models", "index.d.ts")); } foreach (var modelType in codeModel.ModelTemplateModels) { var modelTemplate = new ModelTemplate {Model = modelType}; await Write(modelTemplate, Path.Combine("models", modelType.NameAsFileName.ToCamelCase() + ".js")); } } //MethodGroups if (codeModel.MethodGroupModels.Any()) { var methodGroupIndexTemplate = new MethodGroupIndexTemplate {Model = codeModel}; await Write(methodGroupIndexTemplate, Path.Combine("operations", "index.js")); if (!disableTypeScriptGeneration) { var methodGroupIndexTemplateTS = new MethodGroupIndexTemplateTS {Model = codeModel}; await Write(methodGroupIndexTemplateTS, Path.Combine("operations", "index.d.ts")); } foreach (var methodGroupModel in codeModel.MethodGroupModels) { var methodGroupTemplate = new MethodGroupTemplate {Model = methodGroupModel}; await Write(methodGroupTemplate, Path.Combine("operations", methodGroupModel.TypeName.ToCamelCase() + ".js")); } } }
public override async Task Generate(CodeModel codeModel) { var viewModel = new SampleViewModel(); var model = new SampleModel(); model.Model = viewModel; await Write(model, Path.Combine(Settings.Instance.ModelsName, "Pet.cs")); }
/// <summary> /// Generates code and outputs it in the file system. /// </summary> /// <param name="codeModel"></param> /// <returns></returns> public virtual /* async */ Task Generate(CodeModel codeModel) { ResetFileList(); // since we're not actually async, return a completed task. return "".AsResultTask(); }
/// <summary> /// Normalizes client model using Azure-specific extensions. /// </summary> /// <param name="codeModelient">Service client</param> /// <param name="settings">AutoRest settings</param> /// <param name="codeNamer">AutoRest settings</param> /// <returns></returns> public static void NormalizeAzureClientModel(CodeModel codeModel) { var settings = Settings.Instance; using (NewContext) { settings = new Settings().LoadFrom(settings); settings.AddCredentials = true; if (codeModel == null) { throw new ArgumentNullException("codeModel"); } // This extension from general extensions must be run prior to Azure specific extensions. ProcessParameterizedHost(codeModel); ProcessClientRequestIdExtension(codeModel); UpdateHeadMethods(codeModel); ParseODataExtension(codeModel); ProcessGlobalParameters(codeModel); FlattenModels(codeModel); FlattenMethodParameters(codeModel); ParameterGroupExtensionHelper.AddParameterGroups(codeModel); AddLongRunningOperations(codeModel); AddAzureProperties(codeModel); SetDefaultResponses(codeModel); AddPageableMethod(codeModel); } }
/// <summary> /// Normalizes client model using generic extensions. /// </summary> /// <param name="codeModelient">Service client</param> /// <param name="settings">AutoRest settings</param> /// <returns></returns> public static void NormalizeClientModel(CodeModel codeModel) { ProcessGlobalParameters(codeModel); FlattenModels(codeModel); FlattenMethodParameters(codeModel); ParameterGroupExtensionHelper.AddParameterGroups(codeModel); ProcessParameterizedHost(codeModel); }
/// <summary> /// Generates C# code for service client. /// </summary> /// <param name="cm"></param> /// <returns></returns> public override async Task Generate(CodeModel cm) { // get c# specific codeModel var codeModel = cm as CodeModelCs; if (codeModel == null) { throw new InvalidCastException("CodeModel is not a c# CodeModel"); } // Service client var serviceClientTemplate = new ServiceClientTemplate{ Model = codeModel }; await Write(serviceClientTemplate, $"{codeModel.Name}{ImplementationFileExtension}" ); // Service client interface var serviceClientInterfaceTemplate = new ServiceClientInterfaceTemplate { Model = codeModel }; await Write(serviceClientInterfaceTemplate, $"I{codeModel.Name}{ImplementationFileExtension}"); // operations foreach (MethodGroupCs methodGroup in codeModel.Operations) { if(!methodGroup.Name.IsNullOrEmpty()) { // Operation var operationsTemplate = new MethodGroupTemplate { Model = methodGroup }; await Write(operationsTemplate, $"{operationsTemplate.Model.TypeName}{ImplementationFileExtension}"); // Operation interface var operationsInterfaceTemplate = new MethodGroupInterfaceTemplate { Model = methodGroup }; await Write(operationsInterfaceTemplate, $"I{operationsInterfaceTemplate.Model.TypeName}{ImplementationFileExtension}"); } var operationExtensionsTemplate = new ExtensionsTemplate { Model = methodGroup }; await Write(operationExtensionsTemplate, $"{methodGroup.ExtensionTypeName}Extensions{ImplementationFileExtension}"); } // Models foreach (CompositeTypeCs model in codeModel.ModelTypes.Union(codeModel.HeaderTypes)) { var modelTemplate = new ModelTemplate{ Model = model }; await Write(modelTemplate, Path.Combine(Settings.Instance.ModelsName, $"{model.Name}{ImplementationFileExtension}")); } // Enums foreach (EnumTypeCs enumType in codeModel.EnumTypes) { var enumTemplate = new EnumTemplate { Model = enumType }; await Write(enumTemplate, Path.Combine(Settings.Instance.ModelsName, $"{enumTemplate.Model.Name}{ImplementationFileExtension}")); } // Exceptions foreach (CompositeTypeCs exceptionType in codeModel.ErrorTypes) { var exceptionTemplate = new ExceptionTemplate { Model = exceptionType, }; await Write(exceptionTemplate, Path.Combine(Settings.Instance.ModelsName, $"{exceptionTemplate.Model.ExceptionTypeDefinitionName}{ImplementationFileExtension}")); } }
public override async Task Generate(CodeModel serviceClient) { IDictionary<string, ResourceSchema> resourceSchemas = ResourceSchemaParser.Parse(serviceClient); foreach (string resourceProvider in resourceSchemas.Keys) { StringWriter stringWriter = new StringWriter(); ResourceSchemaWriter.Write(stringWriter, resourceSchemas[resourceProvider]); // string schemaPath = Path.Combine(Settings.Instance.OutputDirectory,); await Write(stringWriter.ToString(), resourceProvider + ".json"); } }
/// <summary> /// Changes head method return type. /// </summary> /// <param name="codeModelient">Service client</param> public static void UpdateHeadMethods(CodeModel codeModel) { if (codeModel == null) { throw new ArgumentNullException("codeModel"); } foreach (var method in codeModel.Methods.Where(m => m.HttpMethod == HttpMethod.Head) .Where(m => m.ReturnType.Body == null)) { HttpStatusCode successStatusCode = method.Responses.Keys.FirstOrDefault(AzureExtensions.HttpHeadStatusCodeSuccessFunc); if (method.Responses.Count == 2 && successStatusCode != default(HttpStatusCode) && method.Responses.ContainsKey(HttpStatusCode.NotFound)) { method.ReturnType = new Response(New<PrimaryType>(KnownPrimaryType.Boolean), method.ReturnType.Headers); } else { Logger.LogInfo(string.Format(CultureInfo.InvariantCulture, Resources.HeadMethodPossibleIncorrectSpecification, method.Name)); } } }
/// <summary> /// Generates Ruby code for Azure service client. /// </summary> /// <param name="cm">The code model.</param> /// <returns>Async tasks which generates SDK files.</returns> public override async Task Generate(CodeModel cm) { var codeModel = cm as CodeModelRba; if (codeModel == null) { throw new InvalidCastException("CodeModel is not a Azure Ruby code model."); } // Service client var serviceClientTemplate = new ServiceClientTemplate { Model = codeModel }; await Write(serviceClientTemplate, Path.Combine(GeneratorSettingsRba.Instance.sdkPath, CodeNamer.UnderscoreCase(codeModel.Name) + ImplementationFileExtension)); // Operations foreach (MethodGroupRba group in codeModel.Operations.Where(each => !each.IsCodeModelMethodGroup)) { // Operation var operationsTemplate = new AzureMethodGroupTemplate { Model = group }; await Write(operationsTemplate, Path.Combine(GeneratorSettingsRba.Instance.sdkPath, CodeNamer.UnderscoreCase(operationsTemplate.Model.TypeName) + ImplementationFileExtension)); } // Models foreach (CompositeTypeRba model in codeModel.ModelTypes) { if ((model.Extensions.ContainsKey(AzureExtensions.ExternalExtension) && (bool)model.Extensions[AzureExtensions.ExternalExtension]) || model.Name == "Resource" || model.Name == "SubResource") { continue; } if( codeModel.pageModels.Any( each => each.Name.EqualsIgnoreCase(model.Name ) ) ) { // Skip, handled in the .pageModels section below. continue; } var modelTemplate = new ModelTemplate { Model = model }; await Write(modelTemplate, Path.Combine(GeneratorSettingsRb.Instance.modelsPath, CodeNamer.UnderscoreCase(model.Name) + ImplementationFileExtension)); } // Paged Models foreach (var pageModel in codeModel.pageModels) { var pageTemplate = new PageModelTemplate { Model = pageModel }; await Write(pageTemplate, Path.Combine(GeneratorSettingsRb.Instance.modelsPath, CodeNamer.UnderscoreCase(pageModel.Name) + ImplementationFileExtension)); } // Enums foreach (EnumTypeRb enumType in codeModel.EnumTypes) { var enumTemplate = new EnumTemplate { Model = enumType }; await Write(enumTemplate, Path.Combine(GeneratorSettingsRb.Instance.modelsPath, CodeNamer.UnderscoreCase(enumTemplate.Model.Name) + ImplementationFileExtension)); } // Requirements var requirementsTemplate = new RequirementsTemplate{Model = new RequirementsRba(codeModel, this)}; await Write(requirementsTemplate, CodeNamer.UnderscoreCase(GeneratorSettingsRb.Instance.packageName ?? GeneratorSettingsRb.Instance.sdkName) + ImplementationFileExtension); // Version File if (GeneratorSettingsRb.Instance.packageVersion != null) { var versionTemplate = new VersionTemplate { Model = GeneratorSettingsRb.Instance.packageVersion }; await Write(versionTemplate, Path.Combine(GeneratorSettingsRb.Instance.sdkPath, "version" + ImplementationFileExtension)); } // Module Definition File if (Settings.Instance.Namespace != null) { var modTemplate = new ModuleDefinitionTemplate { Model = GeneratorSettingsRb.Instance.ModuleDeclarations }; await Write(modTemplate, Path.Combine(GeneratorSettingsRb.Instance.sdkPath, "module_definition" + ImplementationFileExtension)); } }
/// <summary> /// Set default response to CloudError if not defined explicitly. /// </summary> /// <param name="codeModelient"></param> public static void SetDefaultResponses(CodeModel codeModel) { if (codeModel == null) { throw new ArgumentNullException("codeModel"); } // Create CloudError if not already defined CompositeType cloudError = codeModel.ModelTypes.FirstOrDefault(c => c.Name.EqualsIgnoreCase("cloudError")); if (cloudError == null) { cloudError = New<CompositeType>( new { Name = "cloudError", SerializedName = "cloudError" }); cloudError.Extensions[ExternalExtension] = true; codeModel.Add(cloudError); } // Set default response if not defined explicitly foreach (var method in codeModel.Methods) { if (method.DefaultResponse.Body == null && method.ReturnType.Body != null) { method.DefaultResponse = new Response(cloudError, method.ReturnType.Headers); } } }
/// <summary> /// Converts Azure Parameters to regular parameters. /// </summary> /// <param name="codeModelient">Service client</param> public static void ParseODataExtension(CodeModel codeModel) { if (codeModel == null) { throw new ArgumentNullException("codeModel"); } foreach (var method in codeModel.Methods.Where(m => m.Extensions.ContainsKey(ODataExtension))) { string odataModelPath = (string) method.Extensions[ODataExtension]; if (odataModelPath == null) { throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, Resources.ODataEmpty, ODataExtension)); } odataModelPath = odataModelPath.StripDefinitionPath(); CompositeType odataType = codeModel.ModelTypes .FirstOrDefault(t => t.Name.EqualsIgnoreCase(odataModelPath)); if (odataType == null) { throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, Resources.ODataInvalidReferance, ODataExtension)); } var filterParameter = method.Parameters .FirstOrDefault(p => p.Location == ParameterLocation.Query && p.Name.FixedValue == "$filter"); if (filterParameter == null) { throw new InvalidOperationException( string.Format(CultureInfo.InvariantCulture, Resources.ODataFilterMissing, ODataExtension)); } filterParameter.ModelType = odataType; } }
public static void ProcessParameterizedHost(CodeModel codeModel) { using (NewContext) { if (codeModel == null) { throw new ArgumentNullException("codeModel"); } if (codeModel.Extensions.ContainsKey(ParameterizedHostExtension) && !hostChecked) { SwaggerModeler modeler = new SwaggerModeler(); modeler.Build(); var hostExtension = codeModel.Extensions[ParameterizedHostExtension] as JObject; if (hostExtension != null) { var hostTemplate = (string) hostExtension["hostTemplate"]; var parametersJson = hostExtension["parameters"].ToString(); var useSchemePrefix = true; if (hostExtension[UseSchemePrefix] != null) { useSchemePrefix = bool.Parse(hostExtension[UseSchemePrefix].ToString()); } var position = "first"; if (hostExtension[PositionInOperation] != null) { var pat = "^(fir|la)st$"; Regex r = new Regex(pat, RegexOptions.IgnoreCase); var text = hostExtension[PositionInOperation].ToString(); Match m = r.Match(text); if (!m.Success) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Resources.InvalidExtensionProperty, text, PositionInOperation, ParameterizedHostExtension, "first, last")); } position = text; } if (!string.IsNullOrEmpty(parametersJson)) { var jsonSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.None, MetadataPropertyHandling = MetadataPropertyHandling.Ignore }; var swaggerParams = JsonConvert.DeserializeObject<List<SwaggerParameter>>(parametersJson, jsonSettings); List<Parameter> hostParamList = new List<Parameter>(); foreach (var swaggerParameter in swaggerParams) { // Build parameter var parameterBuilder = new ParameterBuilder(swaggerParameter, modeler); var parameter = parameterBuilder.Build(); // check to see if the parameter exists in properties, and needs to have its name normalized if (codeModel.Properties.Any(p => p.SerializedName.EqualsIgnoreCase(parameter.SerializedName))) { parameter.ClientProperty = codeModel.Properties.Single( p => p.SerializedName.Equals(parameter.SerializedName)); } parameter.Extensions["hostParameter"] = true; hostParamList.Add(parameter); } foreach (var method in codeModel.Methods) { if (position.EqualsIgnoreCase("first")) { method.InsertRange(((IEnumerable<Parameter>)hostParamList).Reverse()); } else { method.AddRange(hostParamList); } } if (useSchemePrefix) { codeModel.BaseUrl = string.Format(CultureInfo.InvariantCulture, "{0}://{1}{2}", modeler.ServiceDefinition.Schemes[0].ToString().ToLowerInvariant(), hostTemplate, modeler.ServiceDefinition.BasePath); } else { codeModel.BaseUrl = string.Format(CultureInfo.InvariantCulture, "{0}{1}", hostTemplate, modeler.ServiceDefinition.BasePath); } } } } } hostChecked = true; }
/// <summary> /// Creates long running operation methods. /// </summary> /// <param name="codeModelient"></param> public static void AddLongRunningOperations(CodeModel codeModel) { if (codeModel == null) { throw new ArgumentNullException("codeModel"); } foreach( var method in codeModel.Methods.Where( each => each.Extensions.ContainsKey(LongRunningExtension)).Distinct( each => each.Group + each.Name ).ToArray()) { var isLongRunning = method.Extensions[LongRunningExtension]; if (true == isLongRunning as bool?) { // copy the method var m = Duplicate(method); // change the name, remove the extension. m.Name = "Begin" + m.Name.ToPascalCase(); m.Extensions.Remove(LongRunningExtension); codeModel.Add(m); } } }
/// <summary> /// Flattens the request payload if the number of properties of the /// payload is less than or equal to the PayloadFlatteningThreshold. /// </summary> /// <param name="codeModelient">Service client</param> /// <param name="settings">AutoRest settings</param> public static void FlattenMethodParameters(CodeModel codeModel) { if (codeModel == null) { throw new ArgumentNullException("codeModel"); } foreach (var method in codeModel.Methods) { var bodyParameter = method.Parameters.FirstOrDefault( p => p.Location == ParameterLocation.Body); if (bodyParameter != null) { var bodyParameterType = bodyParameter.ModelType as CompositeType; if (bodyParameterType != null && (bodyParameterType.ComposedProperties.Count(p => !p.IsConstant && !p.IsReadOnly) <= Settings.Instance.PayloadFlatteningThreshold || bodyParameter.ShouldBeFlattened())) { var parameterTransformation = new ParameterTransformation { OutputParameter = bodyParameter }; method.InputParameterTransformation.Add(parameterTransformation); method.Remove(bodyParameter); foreach (var property in bodyParameterType.ComposedProperties.Where(p => !p.IsConstant && p.Name != null && !p.IsReadOnly)) { var newMethodParameter = New<Parameter>(); newMethodParameter.LoadFrom(property); var documentationString = !string.IsNullOrEmpty(property.Summary) ? property.Summary + " " : string.Empty; documentationString += property.Documentation; newMethodParameter.Documentation = documentationString; bodyParameter.Extensions.ForEach(kv => { newMethodParameter.Extensions[kv.Key] = kv.Value; }); method.Add(newMethodParameter); parameterTransformation.ParameterMappings.Add(new ParameterMapping { InputParameter = newMethodParameter, OutputParameterProperty = property.GetClientName() }); } } } } }
/// <summary> /// Parse a ResourceSchemaModel from the provided ServiceClient. /// </summary> /// <param name="serviceClient"></param> /// <returns></returns> public static IDictionary<string, ResourceSchema> Parse(CodeModel serviceClient) { if (serviceClient == null) { throw new ArgumentNullException(nameof(serviceClient)); } string apiVersion = serviceClient.ApiVersion; if (string.IsNullOrWhiteSpace(apiVersion)) { throw new ArgumentException("No API version is provided in the swagger document."); } Dictionary<string, ResourceSchema> resourceSchemas = new Dictionary<string, ResourceSchema>(); foreach (Method method in serviceClient.Methods) { if (method.HttpMethod != HttpMethod.Put || string.IsNullOrWhiteSpace(method.Url) || !method.Url.Value.StartsWith(resourceMethodPrefix, StringComparison.OrdinalIgnoreCase) || !method.Url.Value.EndsWith("}", StringComparison.OrdinalIgnoreCase)) { continue; } string afterPrefix = method.Url.Value.Substring(resourceMethodPrefix.Length); int forwardSlashIndexAfterProvider = afterPrefix.IndexOf('/'); string resourceProvider = afterPrefix.Substring(0, forwardSlashIndexAfterProvider); if (IsPathVariable(resourceProvider)) { // If the resourceProvider is a path variable, such as {someValue}, then this // is not a create resource method. Skip it. continue; } ResourceSchema resourceSchema; if (!resourceSchemas.ContainsKey(resourceProvider)) { resourceSchema = new ResourceSchema(); resourceSchema.Id = string.Format(CultureInfo.InvariantCulture, "http://schema.management.azure.com/schemas/{0}/{1}.json#", apiVersion, resourceProvider); resourceSchema.Title = resourceProvider; resourceSchema.Description = resourceProvider.Replace('.', ' ') + " Resource Types"; resourceSchema.Schema = "http://json-schema.org/draft-04/schema#"; resourceSchemas.Add(resourceProvider, resourceSchema); } else { resourceSchema = resourceSchemas[resourceProvider]; } string methodUrlPathAfterProvider = afterPrefix.Substring(forwardSlashIndexAfterProvider + 1); string[] resourceTypes = ParseResourceTypes(resourceProvider, methodUrlPathAfterProvider, method); foreach (string resourceType in resourceTypes) { JsonSchema resourceDefinition = new JsonSchema(); resourceDefinition.JsonType = "object"; resourceDefinition.AddProperty("type", JsonSchema.CreateStringEnum(resourceType), true); resourceDefinition.AddProperty("apiVersion", JsonSchema.CreateStringEnum(apiVersion), true); if (method.Body != null) { CompositeType body = method.Body.ModelType as CompositeType; // Debug.Assert(body != null, "The create resource method's body must be a CompositeType and cannot be null."); if (body != null) { foreach (Property property in body.ComposedProperties) { if (!resourceDefinition.Properties.Keys.Contains(property.Name.RawValue)) { JsonSchema propertyDefinition = ParseType(property, property.ModelType, resourceSchema.Definitions, serviceClient.ModelTypes); if (propertyDefinition != null) { resourceDefinition.AddProperty(property.Name.RawValue, propertyDefinition, property.IsRequired || property.Name.RawValue == "properties"); } } } } } resourceDefinition.Description = resourceType; string resourcePropertyName = resourceType.Substring(resourceProvider.Length + 1).Replace('/', '_'); Debug.Assert(!resourceSchema.ResourceDefinitions.ContainsKey(resourcePropertyName)); resourceSchema.AddResourceDefinition(resourcePropertyName, resourceDefinition); } } // This loop adds child resource schemas to their parent resource schemas. We can't do // this until we're done adding all resources as top level resources, though, because // it's possible that we will parse a child resource before we parse the parent // resource. foreach (ResourceSchema resourceSchema in resourceSchemas.Values) { // By iterating over the reverse order of the defined resource definitions, I'm // counting on the resource definitions being in sorted order. That way I'm // guaranteed to visit child resource definitions before I visit their parent // resource definitions. By doing this, I've guaranteed that grandchildren resource // definitions will be added to their grandparent (and beyond) ancestor // resource definitions. foreach (string resourcePropertyName in resourceSchema.ResourceDefinitions.Keys.Reverse()) { JsonSchema resourceDefinition = resourceSchema.ResourceDefinitions[resourcePropertyName]; string resourceType = resourceDefinition.ResourceType; int lastSlashIndex = resourceType.LastIndexOf('/'); string parentResourceType = resourceType.Substring(0, lastSlashIndex); JsonSchema parentResourceDefinition = resourceSchema.GetResourceDefinitionByResourceType(parentResourceType); if (parentResourceDefinition != null) { string childResourceType = resourceType.Substring(lastSlashIndex + 1); JsonSchema childResourceDefinition = resourceDefinition.Clone(); childResourceDefinition.ResourceType = childResourceType; string childResourceDefinitionPropertyName = string.Join("_", resourcePropertyName, "childResource"); resourceSchema.AddDefinition(childResourceDefinitionPropertyName, childResourceDefinition); JsonSchema childResources; if (parentResourceDefinition.Properties.ContainsKey("resources")) { childResources = parentResourceDefinition.Properties["resources"]; } else { childResources = new JsonSchema() { JsonType = "array", Items = new JsonSchema() }; parentResourceDefinition.AddProperty("resources", childResources); } childResources.Items.AddOneOf(new JsonSchema() { Ref = "#/definitions/" + childResourceDefinitionPropertyName, }); } } } return resourceSchemas; }
/// <summary> /// Creates azure specific properties. /// </summary> /// <param name="codeModelient"></param> public static void AddAzureProperties(CodeModel codeModel) { if (codeModel == null) { throw new ArgumentNullException("codeModel"); } var apiVersion = codeModel.Properties .FirstOrDefault(p => ApiVersion.EqualsIgnoreCase(p.SerializedName)); if (apiVersion != null) { apiVersion.DefaultValue = codeModel.ApiVersion; apiVersion.IsReadOnly = true; apiVersion.IsRequired = false; } var subscriptionId = codeModel.Properties.FirstOrDefault( p => p.Name.EqualsIgnoreCase( "subscriptionId")); if (subscriptionId != null) { subscriptionId.IsRequired = true; } var acceptLanguage = codeModel.Properties .FirstOrDefault(p => AcceptLanguage.EqualsIgnoreCase(p.SerializedName)); if (acceptLanguage == null) { acceptLanguage = New<Property>(new { Name = AcceptLanguage, Documentation = "Gets or sets the preferred language for the response.", SerializedName = AcceptLanguage, DefaultValue = "en-US" }); codeModel.Add( acceptLanguage); } acceptLanguage.IsReadOnly = false; acceptLanguage.IsRequired = false; acceptLanguage.ModelType = New<PrimaryType>(KnownPrimaryType.String); codeModel.Methods .Where(m => !m.Parameters.Any(p => AcceptLanguage.EqualsIgnoreCase(p.SerializedName))) .ForEach(m2 => m2.Add(New<Parameter>(new { ClientProperty = acceptLanguage, Location = ParameterLocation.Header }).LoadFrom(acceptLanguage))); codeModel.Insert(New<Property>(new { Name = "Credentials", SerializedName = "credentials", ModelType = New<PrimaryType>(KnownPrimaryType.Credentials), IsRequired = true, IsReadOnly = true, Documentation = "Credentials needed for the client to connect to Azure." })); codeModel.Add(New<Property>(new { Name = "LongRunningOperationRetryTimeout", SerializedName = "longRunningOperationRetryTimeout", ModelType = New<PrimaryType>(KnownPrimaryType.Int), Documentation = "Gets or sets the retry timeout in seconds for Long Running Operations. Default value is 30.", DefaultValue = "30" })); codeModel.Add( New<Property>(new { Name = "GenerateClientRequestId", SerializedName = "generateClientRequestId", ModelType = New<PrimaryType>(KnownPrimaryType.Boolean), Documentation = "When set to true a unique x-ms-client-request-id value is generated and included in each request. Default is true.", DefaultValue = "true" })); }
/// <summary> /// Generate Python client code for given ServiceClient. /// </summary> /// <param name="serviceClient"></param> /// <returns></returns> public override async Task Generate(CodeModel cm) { var codeModel = cm as CodeModelPy; if (codeModel == null) { throw new Exception("Code model is not a Python Code Model"); } // Service client var setupTemplate = new SetupTemplate { Model = codeModel }; await Write(setupTemplate, "setup.py"); var serviceClientInitTemplate = new ServiceClientInitTemplate { Model = codeModel }; await Write(serviceClientInitTemplate, Path.Combine(codeModel.PackageName, "__init__.py")); var serviceClientTemplate = new ServiceClientTemplate { Model = codeModel }; await Write(serviceClientTemplate, Path.Combine(codeModel.PackageName, codeModel.Name.ToPythonCase() + ".py")); var versionTemplate = new VersionTemplate { Model = codeModel }; await Write(versionTemplate, Path.Combine(codeModel.PackageName, "version.py")); var exceptionTemplate = new ExceptionTemplate { Model = codeModel }; await Write(exceptionTemplate, Path.Combine(codeModel.PackageName, "exceptions.py")); var credentialTemplate = new CredentialTemplate { Model = codeModel }; await Write(credentialTemplate, Path.Combine(codeModel.PackageName, "credentials.py")); //Models if (codeModel.ModelTypes.Any()) { var modelInitTemplate = new ModelInitTemplate { Model = codeModel }; await Write(modelInitTemplate, Path.Combine(codeModel.PackageName, "models", "__init__.py")); foreach (var modelType in codeModel.ModelTemplateModels) { var modelTemplate = new ModelTemplate { Model = modelType }; await Write(modelTemplate, Path.Combine(codeModel.PackageName, "models", ((string)modelType.Name).ToPythonCase() + ".py")); } } //MethodGroups if (codeModel.MethodGroupModels.Any()) { var methodGroupIndexTemplate = new MethodGroupInitTemplate { Model = codeModel }; await Write(methodGroupIndexTemplate, Path.Combine(codeModel.PackageName, "operations", "__init__.py")); foreach (var methodGroupModel in codeModel.MethodGroupModels) { var methodGroupTemplate = new MethodGroupTemplate { Model = methodGroupModel }; await Write(methodGroupTemplate, Path.Combine(codeModel.PackageName, "operations", ((string) methodGroupModel.TypeName).ToPythonCase() + ".py")); } } // Enums if (codeModel.EnumTypes.Any()) { var enumTemplate = new EnumTemplate { Model = codeModel.EnumTypes }; await Write(enumTemplate, Path.Combine(codeModel.PackageName, "models", codeModel.Name.ToPythonCase() + "_enums.py")); } }
/// <summary> /// Adds the parameter groups to operation parameters. /// </summary> /// <param name="codeModelient"></param> public static void AddParameterGroups(CodeModel codeModel) { if (codeModel == null) { throw new ArgumentNullException("codeModel"); } HashSet<CompositeType> generatedParameterGroups = new HashSet<CompositeType>(); foreach (Method method in codeModel.Methods) { //Copy out flattening transformations as they should be the last List<ParameterTransformation> flatteningTransformations = method.InputParameterTransformation.ToList(); method.InputParameterTransformation.Clear(); //This group name is normalized by each languages code generator later, so it need not happen here. IEnumerable<ParameterGroup> parameterGroups = ExtractParameterGroups(method); List<Parameter> parametersToAddToMethod = new List<Parameter>(); List<Parameter> parametersToRemoveFromMethod = new List<Parameter>(); foreach (ParameterGroup parameterGroup in parameterGroups) { CompositeType parameterGroupType = generatedParameterGroups.FirstOrDefault(item => item.Name.RawValue == parameterGroup.Name); if (parameterGroupType == null) { IEnumerable<Method> methodsWhichUseGroup = GetMethodsUsingParameterGroup(codeModel.Methods, parameterGroup); parameterGroupType = New<CompositeType>(parameterGroup.Name,new { Documentation = GenerateParameterGroupModelText(methodsWhichUseGroup) }); generatedParameterGroups.Add(parameterGroupType); //Add to the service client codeModel.Add(parameterGroupType); } foreach (Property property in parameterGroup.ParameterMapping.Keys) { Property matchingProperty = parameterGroupType.Properties.FirstOrDefault( item => item.Name.RawValue == property.Name.RawValue && item.IsReadOnly == property.IsReadOnly && item.DefaultValue .RawValue== property.DefaultValue.RawValue && item.SerializedName.RawValue == property.SerializedName.RawValue); if (matchingProperty == null) { parameterGroupType.Add(property); } } bool isGroupParameterRequired = parameterGroupType.Properties.Any(p => p.IsRequired); //Create the new parameter object based on the parameter group type Parameter newParameter = New<Parameter>(new { Name = parameterGroup.Name, IsRequired = isGroupParameterRequired, Location = ParameterLocation.None, SerializedName = string.Empty, ModelType = parameterGroupType, Documentation = "Additional parameters for the operation" }); parametersToAddToMethod.Add(newParameter); //Link the grouped parameters to their parent, and remove them from the method parameters foreach (Property property in parameterGroup.ParameterMapping.Keys) { Parameter p = parameterGroup.ParameterMapping[property]; var parameterTransformation = new ParameterTransformation { OutputParameter = p }; parameterTransformation.ParameterMappings.Add(new ParameterMapping { InputParameter = newParameter, InputParameterProperty = property.GetClientName() }); method.InputParameterTransformation.Add(parameterTransformation); parametersToRemoveFromMethod.Add(p); } } method.Remove(p => parametersToRemoveFromMethod.Contains(p)); method.AddRange(parametersToAddToMethod); // Copy back flattening transformations if any flatteningTransformations.ForEach(t => method.InputParameterTransformation.Add(t)); } }
/// <summary> /// Adds ListNext() method for each List method with x-ms-pageable extension. /// </summary> /// <param name="codeModelient"></param> /// <param name="codeNamer"></param> public static void AddPageableMethod(CodeModel codeModel) { if (codeModel == null) { throw new ArgumentNullException("codeModel"); } foreach (var method in codeModel.Methods.Distinct(each => each.Group + each.Name).ToArray()) { if (method.Extensions.ContainsKey(PageableExtension)) { var pageableExtension = JsonConvert.DeserializeObject<PageableExtension>(method.Extensions[PageableExtension].ToString()); if (string.IsNullOrWhiteSpace(pageableExtension.NextLinkName)) { continue; } Method nextLinkMethod = null; if (!string.IsNullOrEmpty(pageableExtension.OperationName)) { nextLinkMethod = codeModel.Methods.FirstOrDefault(m => pageableExtension.OperationName.EqualsIgnoreCase(m.SerializedName)); if (nextLinkMethod != null) { nextLinkMethod.Extensions["nextLinkMethod"] = true; method.Extensions["nextMethodName"] = nextLinkMethod.Name; method.Extensions["nextMethodGroup"] = nextLinkMethod.Group; } } if (nextLinkMethod == null) { nextLinkMethod = Duplicate<Method>(method); if (!string.IsNullOrEmpty(pageableExtension.OperationName)) { nextLinkMethod.Name = CodeNamer.Instance.GetMethodName(SwaggerModeler.GetMethodName( new Operation { OperationId = pageableExtension.OperationName })); nextLinkMethod.Group = CodeNamer.Instance.GetMethodGroupName(SwaggerModeler.GetMethodGroup( new Operation { OperationId = pageableExtension.OperationName })); } else { nextLinkMethod.Name = nextLinkMethod.Name + "Next"; } method.Extensions["nextMethodName"] = nextLinkMethod.Name; method.Extensions["nextMethodGroup"] = nextLinkMethod.Group; nextLinkMethod.Extensions["nextLinkMethod"] = true; nextLinkMethod.ClearParameters(); nextLinkMethod.Url = "{nextLink}"; nextLinkMethod.IsAbsoluteUrl = true; var nextLinkParameter = New<Parameter>(new { Name = "nextPageLink", SerializedName = "nextLink", ModelType = New<PrimaryType>(KnownPrimaryType.String), Documentation = "The NextLink from the previous successful call to List operation.", IsRequired = true, Location = ParameterLocation.Path }); nextLinkParameter.Extensions[SkipUrlEncodingExtension] = true; nextLinkMethod.Add(nextLinkParameter); // Need copy all the header parameters from List method to ListNext method foreach (var param in method.Parameters.Where(p => p.Location == ParameterLocation.Header)) { nextLinkMethod.Add(Duplicate(param)); } // Copy all grouped parameters that only contain header parameters nextLinkMethod.InputParameterTransformation.Clear(); method.InputParameterTransformation.GroupBy(t => t.ParameterMappings[0].InputParameter) .ForEach(grouping => { if (grouping.All(t => t.OutputParameter.Location == ParameterLocation.Header)) { // All grouped properties were header parameters, reuse data type nextLinkMethod.Add(grouping.Key); grouping.ForEach(t => nextLinkMethod.InputParameterTransformation.Add(t)); } else if (grouping.Any(t => t.OutputParameter.Location == ParameterLocation.Header)) { // Some grouped properties were header parameters, creating new data types var headerGrouping = grouping.Where(t => t.OutputParameter.Location == ParameterLocation.Header); headerGrouping.ForEach(t => nextLinkMethod.InputParameterTransformation.Add((ParameterTransformation) t.Clone())); var newGroupingParam = CreateParameterFromGrouping(headerGrouping, nextLinkMethod, codeModel); nextLinkMethod.Add(newGroupingParam); //grouping.Key.Name = newGroupingParam.Name; // var inputParameter = (Parameter) nextLinkMethod.InputParameterTransformation.First().ParameterMappings[0].InputParameter.Clone(); var inputParameter = Duplicate(nextLinkMethod.InputParameterTransformation.First().ParameterMappings[0].InputParameter); inputParameter.Name = CodeNamer.Instance.GetParameterName(newGroupingParam.Name); inputParameter.IsRequired = newGroupingParam.IsRequired; nextLinkMethod.InputParameterTransformation.ForEach(t => t.ParameterMappings[0].InputParameter = inputParameter); } }); codeModel.Add( nextLinkMethod); } } } }
public static void ProcessClientRequestIdExtension(CodeModel codeModel) { if (codeModel == null) { throw new ArgumentNullException("codeModel"); } foreach (Method method in codeModel.Methods) { const string defaultClientRequestIdName = "x-ms-client-request-id"; string customClientRequestIdName = method.Parameters.Where(parameter => parameter.Extensions.ContainsKey(ClientRequestIdExtension)) .Select(parameter => { bool? extensionObject = parameter.Extensions[ClientRequestIdExtension] as bool?; if (extensionObject != null && extensionObject.Value) { return parameter.SerializedName.Value; } return null; }) .SingleOrDefault(); string clientRequestIdName = customClientRequestIdName ?? defaultClientRequestIdName; method.Extensions.Add(ClientRequestIdExtension, clientRequestIdName); } }
private static Parameter CreateParameterFromGrouping(IEnumerable<ParameterTransformation> grouping, Method method, CodeModel codeModel) { var properties = new List<Property>(); string parameterGroupName = null; foreach (var parameter in grouping.Select(g => g.OutputParameter)) { Newtonsoft.Json.Linq.JContainer extensionObject = parameter.Extensions[ParameterGroupExtension] as Newtonsoft.Json.Linq.JContainer; string specifiedGroupName = extensionObject.Value<string>("name"); if (specifiedGroupName == null) { string postfix = extensionObject.Value<string>("postfix") ?? "Parameters"; parameterGroupName = method.Group + "-" + method.Name + "-" + postfix; } else { parameterGroupName = specifiedGroupName; } Property groupProperty = New<Property>(new { IsReadOnly = false, //Since these properties are used as parameters they are never read only Name = parameter.Name, IsRequired = parameter.IsRequired, DefaultValue = parameter.DefaultValue, //Constraints = parameter.Constraints, Omit these since we don't want to perform parameter validation Documentation = parameter.Documentation, ModelType = parameter.ModelType, SerializedName = default(string) //Parameter is never serialized directly }); properties.Add(groupProperty); } var parameterGroupType = New <CompositeType>(parameterGroupName, new { Documentation = "Additional parameters for the " + method.Name + " operation." }); //Add to the service client codeModel.Add(parameterGroupType); foreach (Property property in properties) { parameterGroupType.Add(property); } bool isGroupParameterRequired = parameterGroupType.Properties.Any(p => p.IsRequired); //Create the new parameter object based on the parameter group type return New<Parameter>(new { Name = parameterGroupName, IsRequired = isGroupParameterRequired, Location = ParameterLocation.None, SerializedName = string.Empty, ModelType = parameterGroupType, Documentation = "Additional parameters for the operation" }); }
public static CodeModel RunExtensions(Trigger trigger, CodeModel codeModel) { /* foreach (var extension in extensions.Where(each => each.trigger == trugger).SortBy(each => each.Priority)) codeModel = extension.Transform(codeModel); */ return codeModel; }
/// <summary> /// Flattens the Resource Properties. /// </summary> /// <param name="codeModelient"></param> public static void FlattenModels(CodeModel codeModel) { if (codeModel == null) { throw new ArgumentNullException("codeModel"); } HashSet<string> typesToDelete = new HashSet<string>(); foreach (var compositeType in codeModel.ModelTypes) { if (compositeType.Properties.Any(p => p.ShouldBeFlattened()) && !typesToDelete.Contains(compositeType.Name)) { List<Property> oldProperties = compositeType.Properties.ToList(); compositeType.ClearProperties(); foreach (Property innerProperty in oldProperties) { if (innerProperty.ShouldBeFlattened() && compositeType != innerProperty.ModelType) { FlattenProperty(innerProperty, typesToDelete) .ForEach(p => compositeType.Add(p)); } else { compositeType.Add(innerProperty); } } RemoveFlatteningConflicts(compositeType); } } RemoveUnreferencedTypes(codeModel, typesToDelete); }
/// <summary> /// Generate Python client code for given ServiceClient. /// </summary> /// <param name="cm"></param> /// <returns></returns> public override async Task Generate(CodeModel cm) { var codeModel = cm as CodeModelPya; if (codeModel == null) { throw new Exception("CodeModel is not a Python Azure Code Model"); } // Service client var setupTemplate = new SetupTemplate { Model = codeModel }; await Write(setupTemplate, "setup.py"); var serviceClientInitTemplate = new ServiceClientInitTemplate { Model = codeModel }; await Write(serviceClientInitTemplate, Path.Combine(codeModel.PackageName, "__init__.py")); var serviceClientTemplate = new AzureServiceClientTemplate { Model = codeModel, }; await Write(serviceClientTemplate, Path.Combine(codeModel.PackageName, codeModel.Name.ToPythonCase() + ".py")); var versionTemplate = new VersionTemplate { Model = codeModel, }; await Write(versionTemplate, Path.Combine(codeModel.PackageName, "version.py")); var exceptionTemplate = new ExceptionTemplate { Model = codeModel, }; await Write(exceptionTemplate, Path.Combine(codeModel.PackageName, "exceptions.py")); var credentialTemplate = new CredentialTemplate { Model = codeModel, }; await Write(credentialTemplate, Path.Combine(codeModel.PackageName, "credentials.py")); //Models var models = codeModel.ModelTemplateModels.Where(each => !each.Extensions.ContainsKey(AzureExtensions.ExternalExtension)); if (models.Any()) { var modelInitTemplate = new AzureModelInitTemplate { Model = codeModel }; await Write(modelInitTemplate, Path.Combine(codeModel.PackageName, "models", "__init__.py")); foreach (var modelType in models) { var modelTemplate = new ModelTemplate { Model = modelType }; await Write(modelTemplate, Path.Combine(codeModel.PackageName, "models", modelType.Name.ToPythonCase() + ".py")); } } //MethodGroups if (codeModel.MethodGroupModels.Any()) { var methodGroupIndexTemplate = new MethodGroupInitTemplate { Model = codeModel }; await Write(methodGroupIndexTemplate, Path.Combine(codeModel.PackageName, "operations", "__init__.py")); foreach (var methodGroupModel in codeModel.MethodGroupModels) { var methodGroupTemplate = new AzureMethodGroupTemplate { Model = methodGroupModel as MethodGroupPya }; await Write(methodGroupTemplate, Path.Combine(codeModel.PackageName, "operations", ((string) methodGroupModel.TypeName).ToPythonCase() + ".py")); } } // Enums if (codeModel.EnumTypes.Any()) { var enumTemplate = new EnumTemplate { Model = codeModel.EnumTypes }; await Write(enumTemplate, Path.Combine(codeModel.PackageName, "models", codeModel.Name.ToPythonCase() + "_enums.py")); } // Page class foreach (var pageModel in codeModel.PageModels) { var pageTemplate = new PageTemplate { Model = pageModel }; await Write(pageTemplate, Path.Combine(codeModel.PackageName, "models", pageModel.TypeDefinitionName.ToPythonCase() + ".py")); } }
/// <summary> /// Flattens the Resource Properties. /// </summary> /// <param name="codeModelient"></param> public static void FlattenModels(CodeModel codeModel) { if (codeModel == null) { throw new ArgumentNullException("codeModel"); } // About "flattenDepth": flattening was not really deterministic and depended on order of specification // Sorting by the following method enforces the right behavior Func<IModelType, int, int> flattenDepth = null; flattenDepth = (type, depth) => { var ct = type as CompositeType; if (ReferenceEquals(ct, null) || !ct.Properties.Any(p => p.ShouldBeFlattened()) || depth > 16) return 0; return 1 + ct.Properties.Max(prop => flattenDepth(prop.ModelType, depth + 1)); }; HashSet<string> typesToDelete = new HashSet<string>(); foreach (var compositeType in codeModel.ModelTypes.OrderByDescending(type => flattenDepth(type, 0))) { if (compositeType.Properties.Any(p => p.ShouldBeFlattened()) && !typesToDelete.Contains(compositeType.Name)) { List<Property> oldProperties = compositeType.Properties.ToList(); compositeType.ClearProperties(); foreach (Property innerProperty in oldProperties) { if (innerProperty.ShouldBeFlattened() && compositeType != innerProperty.ModelType) { FlattenProperty(innerProperty, typesToDelete) .ForEach(p => compositeType.Add(p)); } else { compositeType.Add(innerProperty); } } RemoveFlatteningConflicts(compositeType); } } RemoveUnreferencedTypes(codeModel, typesToDelete); }
/// <summary> /// Ensures that global parameters that are tagged with x-ms-paramater-location: "method" are not client properties /// </summary> /// <param name="codeModelient"></param> public static void ProcessGlobalParameters(CodeModel codeModel) { if (codeModel == null) { throw new ArgumentNullException("codeModel"); } List<Property> propertiesToProcess = new List<Property>(); foreach(var property in codeModel.Properties) { if (property.Extensions.ContainsKey(ParameterLocationExtension) && property.Extensions[ParameterLocationExtension].ToString().EqualsIgnoreCase("method")) { propertiesToProcess.Add(property); } } //set the clientProperty to null for such parameters in the method. foreach(var prop in propertiesToProcess) { codeModel.Remove(prop); foreach(var method in codeModel.Operations.SelectMany(each => each.Methods)) { foreach(var parameter in method.Parameters) { if (parameter.Name.FixedValue == prop.Name.FixedValue && parameter.IsClientProperty) { parameter.ClientProperty = null; } } } } }
/// <summary> /// Cleans all model types that are not used /// </summary> /// <param name="codeModelient"></param> /// <param name="typeNames"></param> public static void RemoveUnreferencedTypes(CodeModel codeModel, HashSet<string> typeNames) { if (codeModel == null) { throw new ArgumentNullException("codeModel"); } if (typeNames == null) { throw new ArgumentNullException("typeNames"); } while (typeNames.Count > 0) { string typeName = typeNames.First(); typeNames.Remove(typeName); var typeToDelete = codeModel.ModelTypes.First(t => t.Name == typeName); var isUsedInErrorTypes = codeModel.ErrorTypes.Any(e => e.Name == typeName); var isUsedInResponses = codeModel.Methods.Any(m => m.Responses.Any(r => r.Value.Body == typeToDelete)); var isUsedInParameters = codeModel.Methods.Any(m => m.Parameters.Any(p => p.ModelType == typeToDelete)); var isBaseType = codeModel.ModelTypes.Any(t => t.BaseModelType == typeToDelete); var isUsedInProperties = codeModel.ModelTypes.Where(t => !typeNames.Contains(t.Name)) .Any(t => t.Properties.Any(p => p.ModelType == typeToDelete)); if (!isUsedInErrorTypes && !isUsedInResponses && !isUsedInParameters && !isBaseType && !isUsedInProperties) { codeModel.Remove(typeToDelete); } } }
/// <summary> /// Generates C# code for service client. /// </summary> /// <param name="cm"></param> /// <returns></returns> public override async Task Generate(CodeModel cm) { var codeModel = cm as CodeModelCsa; if (codeModel == null) { throw new InvalidCastException("CodeModel is not a Azure c# CodeModel"); } // Service client var serviceClientTemplate = new AzureServiceClientTemplate { Model = codeModel }; await Write(serviceClientTemplate, $"{codeModel.Name}{ImplementationFileExtension}"); // Service client interface var serviceClientInterfaceTemplate = new ServiceClientInterfaceTemplate { Model = codeModel }; await Write(serviceClientInterfaceTemplate, "I" + codeModel.Name + ImplementationFileExtension); // Operations foreach (MethodGroupCs group in codeModel.Operations) { if (!group.IsCodeModelMethodGroup) { // Operation var operationsTemplate = new AzureMethodGroupTemplate { Model = group }; await Write(operationsTemplate, operationsTemplate.Model.TypeName + ImplementationFileExtension); // Operation interface var operationsInterfaceTemplate = new MethodGroupInterfaceTemplate { Model = group }; await Write(operationsInterfaceTemplate, $"I{operationsInterfaceTemplate.Model.TypeName}{ImplementationFileExtension}"); } var operationExtensionsTemplate = new ExtensionsTemplate { Model = group }; await Write(operationExtensionsTemplate, $"{group.ExtensionTypeName}Extensions{ImplementationFileExtension}"); } // Models foreach (CompositeTypeCs model in codeModel.ModelTypes.Concat(codeModel.HeaderTypes)) { if (model.Extensions.ContainsKey(AzureExtensions.ExternalExtension) && (bool)model.Extensions[AzureExtensions.ExternalExtension]) { continue; } if (model.IsResource()) { continue; } var modelTemplate = new ModelTemplate { Model = model }; await Write(modelTemplate, Path.Combine(Settings.Instance.ModelsName, $"{model.Name}{ImplementationFileExtension}")); } // Enums foreach (EnumTypeCs enumType in codeModel.EnumTypes) { var enumTemplate = new EnumTemplate { Model = enumType }; await Write(enumTemplate, Path.Combine(Settings.Instance.ModelsName, $"{enumTemplate.Model.Name}{ImplementationFileExtension}")); } // Page class foreach (var pageClass in codeModel.pageClasses) { var pageTemplate = new PageTemplate { Model = new Page(pageClass.Value, pageClass.Key.Key, pageClass.Key.Value) }; await Write(pageTemplate, Path.Combine(Settings.Instance.ModelsName, $"{pageTemplate.Model.TypeDefinitionName}{ImplementationFileExtension}")); } // Exceptions foreach (CompositeTypeCs exceptionType in codeModel.ErrorTypes) { if (exceptionType.Name == "CloudError") { continue; } var exceptionTemplate = new ExceptionTemplate { Model = exceptionType }; await Write(exceptionTemplate, Path.Combine(Settings.Instance.ModelsName, $"{exceptionTemplate.Model.ExceptionTypeDefinitionName}{ImplementationFileExtension}")); } }
public static string GetExceptionDefinitionTypeIfExists(this CompositeType type, CodeModel serviceClient) { if (type == null) { throw new ArgumentNullException("type"); } if (serviceClient == null) { throw new ArgumentNullException("serviceClient"); } if (serviceClient.ErrorTypes.Contains(type)) { return type.GetExceptionDefineType(); } else { return null; } }