public CodeModel Build(ServiceDefinition serviceDefinition) { ServiceDefinition = serviceDefinition; // Update settings UpdateSettings(); InitializeClientModel(); BuildCompositeTypes(); // Build client parameters foreach (var swaggerParameter in ServiceDefinition.Components.Parameters.Values) { var parameter = ((ParameterBuilder)swaggerParameter.GetBuilder(this)).Build(); var clientProperty = New <Property>(); clientProperty.LoadFrom(parameter); clientProperty.RealPath = new string[] { parameter.SerializedName }; CodeModel.Add(clientProperty); } var baseErrorResponses = new List <Fixable <string> >(); var methods = new List <Method>(); // Build methods foreach (var path in ServiceDefinition.Paths.Concat(ServiceDefinition.CustomPaths)) { foreach (var verb in path.Value.Keys) { var operation = path.Value[verb]; if (string.IsNullOrWhiteSpace(operation.OperationId)) { throw ErrorManager.CreateError( string.Format(CultureInfo.InvariantCulture, Resources.OperationIdMissing, verb, path.Key)); } var methodName = GetMethodNameFromOperationId(operation.OperationId); var methodGroup = GetMethodGroup(operation); if (verb.ToHttpMethod() != HttpMethod.Options) { string url = path.Key; if (url.Contains("?")) { url = url.Substring(0, url.IndexOf('?')); } var method = BuildMethod(verb.ToHttpMethod(), url, methodName, operation); method.Group = methodGroup; methods.Add(method); // Add error models marked by x-ms-error-response var xmsErrorResponses = method.Responses.Values.Where(resp => resp.Extensions.ContainsKey("x-ms-error-response") && (bool)resp.Extensions["x-ms-error-response"] && resp.Body is CompositeType) .Select(resp => (CompositeType)resp.Body); xmsErrorResponses.ForEach(errModel => CodeModel.AddError(errModel)); // If marked error models have a polymorphic discriminator, include all models that allOf on them (at any level of inheritence) baseErrorResponses = baseErrorResponses.Union(xmsErrorResponses.Where(errModel => !string.IsNullOrEmpty(errModel.PolymorphicDiscriminator) && ExtendedTypes.ContainsKey(errModel.Name)) .Select(errModel => errModel.Name)).ToList(); // Add the default error model if exists if (method.DefaultResponse.Body is CompositeType) { baseErrorResponses.Add(((CompositeType)method.DefaultResponse.Body).Name); CodeModel.AddError((CompositeType)method.DefaultResponse.Body); } } else { Logger.Instance.Log(Category.Warning, Resources.OptionsNotSupported); } } } ProcessForwardToMethods(methods); // Set base type foreach (var typeName in GeneratedTypes.Keys) { var objectType = GeneratedTypes[typeName]; if (ExtendedTypes.ContainsKey(typeName)) { objectType.BaseModelType = GeneratedTypes[ExtendedTypes[typeName]]; } CodeModel.Add(objectType); } CodeModel.AddRange(methods); foreach (var k in GeneratedTypes.Keys) { var baseModelType = GeneratedTypes[k].BaseModelType; while (baseModelType != null && baseModelType is CompositeType && !baseErrorResponses.Contains(k)) { if (baseErrorResponses.Contains(baseModelType.Name)) { CodeModel.AddError(GeneratedTypes[k]); break; } baseModelType = baseModelType.BaseModelType; } } // What operation returns it decides whether an object is to be modeled as a // regular model class or an exception class // Set base type var errorResponses = ServiceDefinition.Paths.Values.SelectMany(pathObj => pathObj.Values.SelectMany(opObj => opObj.Responses.Values.Where(res => res.Extensions?.ContainsKey("x-ms-error-response") == true && (bool)res.Extensions["x-ms-error-response"]))); var errorModels = errorResponses.Select(resp => resp.Schema?.Reference).Where(modelRef => !string.IsNullOrEmpty(modelRef)).Select(modelRef => GeneratedTypes[modelRef]); errorModels.ForEach(errorModel => CodeModel.AddError(errorModel)); // Build ContentType enum if (ContentTypeChoices.Count > 0) { var enumType = New <EnumType>(); enumType.ModelAsString = true; enumType.SetName("ContentTypes"); enumType.Values.AddRange(ContentTypeChoices.Select(v => new EnumValue { Name = v, SerializedName = v })); CodeModel.Add(enumType); } ProcessParameterizedHost(); return(CodeModel); }
public CodeModel Build(ServiceDefinition serviceDefinition) { ServiceDefinition = serviceDefinition; // Update settings UpdateSettings(); InitializeClientModel(); BuildCompositeTypes(); // Build client parameters foreach (var swaggerParameter in ServiceDefinition.Components.Parameters.Values) { var parameter = ((ParameterBuilder)swaggerParameter.GetBuilder(this)).Build(); var clientProperty = New <Property>(); clientProperty.LoadFrom(parameter); clientProperty.RealPath = new string[] { parameter.SerializedName }; CodeModel.Add(clientProperty); } var methods = new List <Method>(); // Build methods foreach (var path in ServiceDefinition.Paths.Concat(ServiceDefinition.CustomPaths)) { foreach (var verb in path.Value.Keys) { var operation = path.Value[verb]; if (string.IsNullOrWhiteSpace(operation.OperationId)) { throw ErrorManager.CreateError( string.Format(CultureInfo.InvariantCulture, Resources.OperationIdMissing, verb, path.Key)); } var methodName = GetMethodNameFromOperationId(operation.OperationId); var methodGroup = GetMethodGroup(operation); if (verb.ToHttpMethod() != HttpMethod.Options) { string url = path.Key; if (url.Contains("?")) { url = url.Substring(0, url.IndexOf('?')); } var method = BuildMethod(verb.ToHttpMethod(), url, methodName, operation); method.Group = methodGroup; methods.Add(method); if (method.DefaultResponse.Body is CompositeType) { CodeModel.AddError((CompositeType)method.DefaultResponse.Body); } } else { Logger.Instance.Log(Category.Warning, Resources.OptionsNotSupported); } } } // Set base type foreach (var typeName in GeneratedTypes.Keys) { var objectType = GeneratedTypes[typeName]; if (ExtendedTypes.ContainsKey(typeName)) { objectType.BaseModelType = GeneratedTypes[ExtendedTypes[typeName]]; } CodeModel.Add(objectType); } CodeModel.AddRange(methods); // Build ContentType enum if (ContentTypeChoices.Count > 0) { var enumType = New <EnumType>(); enumType.ModelAsString = true; enumType.SetName("ContentTypes"); enumType.Values.AddRange(ContentTypeChoices.Select(v => new EnumValue { Name = v, SerializedName = v })); CodeModel.Add(enumType); } ProcessParameterizedHost(); return(CodeModel); }
public override CodeModel Build(out IEnumerable <ValidationMessage> messages) { Logger.LogInfo(Resources.ParsingSwagger); if (string.IsNullOrWhiteSpace(Settings.Input)) { throw ErrorManager.CreateError(Resources.InputRequired); } ServiceDefinition = SwaggerParser.Load(Settings.Input, Settings.FileSystem); // Look for semantic errors and warnings in the document. var validator = new RecursiveObjectValidator(PropertyNameResolver.JsonName); messages = validator.GetValidationExceptions(ServiceDefinition).ToList(); Logger.LogInfo(Resources.GeneratingClient); // Update settings UpdateSettings(); InitializeClientModel(); BuildCompositeTypes(); // Build client parameters foreach (var swaggerParameter in ServiceDefinition.Parameters.Values) { var parameter = ((ParameterBuilder)swaggerParameter.GetBuilder(this)).Build(); var clientProperty = New <Property>(); clientProperty.LoadFrom(parameter); CodeModel.Add(clientProperty); } var methods = new List <Method>(); // Build methods foreach (var path in ServiceDefinition.Paths.Concat(ServiceDefinition.CustomPaths)) { foreach (var verb in path.Value.Keys) { var operation = path.Value[verb]; if (string.IsNullOrWhiteSpace(operation.OperationId)) { throw ErrorManager.CreateError( string.Format(CultureInfo.InvariantCulture, Resources.OperationIdMissing, verb, path.Key)); } var methodName = GetMethodName(operation); var methodGroup = GetMethodGroup(operation); if (verb.ToHttpMethod() != HttpMethod.Options) { string url = path.Key; if (url.Contains("?")) { url = url.Substring(0, url.IndexOf('?')); } var method = BuildMethod(verb.ToHttpMethod(), url, methodName, operation); method.Group = methodGroup; methods.Add(method); if (method.DefaultResponse.Body is CompositeType) { CodeModel.AddError((CompositeType)method.DefaultResponse.Body); } } else { Logger.LogWarning(Resources.OptionsNotSupported); } } } // Set base type foreach (var typeName in GeneratedTypes.Keys) { var objectType = GeneratedTypes[typeName]; if (ExtendedTypes.ContainsKey(typeName)) { objectType.BaseModelType = GeneratedTypes[ExtendedTypes[typeName]]; } CodeModel.Add(objectType); } CodeModel.AddRange(methods); return(CodeModel); }
private static CodeModel Merge(CodeModel compositeClient, CodeModel subClient) { if (compositeClient == null) { throw new ArgumentNullException("compositeClient"); } if (subClient == null) { throw new ArgumentNullException("subClient"); } // Merge if (compositeClient.BaseUrl == null) { compositeClient.BaseUrl = subClient.BaseUrl; } else { AssertEquals(compositeClient.BaseUrl, subClient.BaseUrl, "BaseUrl"); } // Copy client properties foreach (var subClientProperty in subClient.Properties) { if (subClientProperty.SerializedName == "api-version") { continue; } var compositeClientProperty = compositeClient.Properties.FirstOrDefault(p => p.Name == subClientProperty.Name); if (compositeClientProperty == null) { compositeClient.Add(subClientProperty); } else { AssertJsonEquals(compositeClientProperty, subClientProperty); } } // Copy models foreach (var subClientModel in subClient.ModelTypes) { var compositeClientModel = compositeClient.ModelTypes.FirstOrDefault(p => p.Name == subClientModel.Name); if (compositeClientModel == null) { compositeClient.Add(subClientModel); } else { AssertJsonEquals(compositeClientModel, subClientModel); } } // Copy enum types foreach (var subClientModel in subClient.EnumTypes) { var compositeClientModel = compositeClient.EnumTypes.FirstOrDefault(p => p.Name == subClientModel.Name); if (compositeClientModel == null) { compositeClient.Add(subClientModel); } else { AssertJsonEquals(compositeClientModel, subClientModel); } } // Copy error types foreach (var subClientModel in subClient.ErrorTypes) { var compositeClientModel = compositeClient.ErrorTypes.FirstOrDefault(p => p.Name == subClientModel.Name); if (compositeClientModel == null) { compositeClient.AddError(subClientModel); } else { AssertJsonEquals(compositeClientModel, subClientModel); } } // Copy header types foreach (var subClientModel in subClient.HeaderTypes) { var compositeClientModel = compositeClient.HeaderTypes.FirstOrDefault(p => p.Name == subClientModel.Name); if (compositeClientModel == null) { compositeClient.AddHeader(subClientModel); } else { AssertJsonEquals(compositeClientModel, subClientModel); } } // Copy methods foreach (var subClientMethod in subClient.Methods) { var apiVersionParameter = subClientMethod.Parameters.FirstOrDefault(p => p.SerializedName == "api-version"); if (apiVersionParameter != null) { apiVersionParameter.ClientProperty = null; apiVersionParameter.IsConstant = true; apiVersionParameter.DefaultValue = subClient.ApiVersion; apiVersionParameter.IsRequired = true; } var compositeClientMethod = compositeClient.Methods.FirstOrDefault(m => m.ToString() == subClientMethod.ToString() && m.Group == subClientMethod.Group); if (compositeClientMethod == null) { // Re-link client parameters foreach (var parameter in subClientMethod.Parameters.Where(p => p.IsClientProperty)) { var clientProperty = compositeClient.Properties .FirstOrDefault(p => p.SerializedName == parameter.ClientProperty.SerializedName); if (clientProperty != null) { parameter.ClientProperty = clientProperty; } } compositeClient.Add(subClientMethod); } } // make sure that properties and parameters are using the types from the new model // and not the types from the original. foreach (var property in compositeClient.Properties) { EnsureUsesTypeFromModel(property, compositeClient); } foreach (var method in compositeClient.Methods) { foreach (var parameter in method.Parameters) { EnsureUsesTypeFromModel(parameter, compositeClient); } method.ReturnType.Body = EnsureUsesTypeFromModel(method.ReturnType.Body, compositeClient); method.ReturnType.Headers = EnsureUsesTypeFromModel(method.ReturnType.Headers, compositeClient); } foreach (var modelType in compositeClient.ModelTypes) { foreach (var property in modelType.Properties) { EnsureUsesTypeFromModel(property, compositeClient); } } return(compositeClient); }
public CodeModel Build(ServiceDefinition serviceDefinition) { ServiceDefinition = serviceDefinition; if (Settings.Instance.CodeGenerator.EqualsIgnoreCase("None")) { // Look for semantic errors and warnings in the document. var validator = new RecursiveObjectValidator(PropertyNameResolver.JsonName); foreach (var validationEx in validator.GetValidationExceptions(ServiceDefinition.FilePath, ServiceDefinition, new ServiceDefinitionMetadata { // LEGACY MODE! set defaults for the metadata, marked to be deprecated ServiceDefinitionDocumentType = ServiceDefinitionDocumentType.ARM, MergeState = ServiceDefinitionDocumentState.Composed })) { Logger.Instance.Log(validationEx); } return(New <CodeModel>()); } Logger.Instance.Log(Category.Info, Resources.GeneratingClient); // Update settings UpdateSettings(); InitializeClientModel(); BuildCompositeTypes(); // Build client parameters foreach (var swaggerParameter in ServiceDefinition.Parameters.Values) { var parameter = ((ParameterBuilder)swaggerParameter.GetBuilder(this)).Build(); var clientProperty = New <Property>(); clientProperty.LoadFrom(parameter); clientProperty.RealPath = new string[] { parameter.SerializedName.Value }; CodeModel.Add(clientProperty); } var methods = new List <Method>(); // Build methods foreach (var path in ServiceDefinition.Paths.Concat(ServiceDefinition.CustomPaths)) { foreach (var verb in path.Value.Keys) { var operation = path.Value[verb]; if (string.IsNullOrWhiteSpace(operation.OperationId)) { throw ErrorManager.CreateError( string.Format(CultureInfo.InvariantCulture, Resources.OperationIdMissing, verb, path.Key)); } var methodName = GetMethodName(operation); var methodGroup = GetMethodGroup(operation); if (verb.ToHttpMethod() != HttpMethod.Options) { string url = path.Key; if (url.Contains("?")) { url = url.Substring(0, url.IndexOf('?')); } var method = BuildMethod(verb.ToHttpMethod(), url, methodName, operation); method.Group = methodGroup; methods.Add(method); if (method.DefaultResponse.Body is CompositeType) { CodeModel.AddError((CompositeType)method.DefaultResponse.Body); } } else { Logger.Instance.Log(Category.Warning, Resources.OptionsNotSupported); } } } // Set base type foreach (var typeName in GeneratedTypes.Keys) { var objectType = GeneratedTypes[typeName]; if (ExtendedTypes.ContainsKey(typeName)) { objectType.BaseModelType = GeneratedTypes[ExtendedTypes[typeName]]; } CodeModel.Add(objectType); } CodeModel.AddRange(methods); return(CodeModel); }