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);
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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);
        }