예제 #1
0
        private void WriteDiagnosticScope(CodeWriter writer, Diagnostic diagnostic, CodeWriterDelegate inner)
        {
            var scopeVariable = new CodeWriterDeclaration("scope");

            writer.Line($"using var {scopeVariable:D} = {ClientDiagnosticsField}.CreateScope({diagnostic.ScopeName:L});");
            foreach (DiagnosticAttribute diagnosticScopeAttributes in diagnostic.Attributes)
            {
                writer.Append($"{scopeVariable}.AddAttribute({diagnosticScopeAttributes.Name:L},");
                writer.WriteReferenceOrConstant(diagnosticScopeAttributes.Value);
                writer.Line($");");
            }

            writer.Line($"{scopeVariable}.Start();");

            using (writer.Scope($"try"))
            {
                inner(writer);
            }

            using (writer.Scope($"catch ({typeof(Exception)} e)"))
            {
                writer.Line($"{scopeVariable}.Failed(e);");
                writer.Line($"throw;");
            }
        }
예제 #2
0
        private void WriteJsonDeserialize(CodeWriter writer, ObjectType model, JsonSerialization jsonSerialization)
        {
            using (writer.Scope($"internal static {model.Type} Deserialize{model.Declaration.Name}({typeof(JsonElement)} element)"))
            {
                if (model.Discriminator?.HasDescendants == true)
                {
                    using (writer.Scope($"if (element.TryGetProperty({model.Discriminator.SerializedName:L}, out {typeof(JsonElement)} discriminator))"))
                    {
                        writer.Line($"switch (discriminator.GetString())");
                        using (writer.Scope())
                        {
                            foreach (var implementation in model.Discriminator.Implementations)
                            {
                                writer
                                .Append($"case {implementation.Key:L}: return ")
                                .DeserializeImplementation(implementation.Type.Implementation, w => w.Append($"element"));
                                writer.Line($";");
                            }
                        }
                    }
                }

                writer.DeserializeValue(jsonSerialization,
                                        w => w.AppendRaw("element"),
                                        (w, v) => w.Line($"return {v};"));
            }
            writer.Line();
        }
예제 #3
0
        private static void DeserializeIntoVariableWithNullHandling(this CodeWriter writer, JsonSerialization serialization, Action <CodeWriter, CodeWriterDelegate> valueCallback, CodeWriterDelegate element)
        {
            CSharpType?type = null;

            switch (serialization)
            {
            case JsonArraySerialization array:
                type = array.Type;
                break;

            case JsonDictionarySerialization dictionary:
                type = dictionary.Type;
                break;

            case JsonValueSerialization valueSerialization:
                type = valueSerialization.Type;
                break;
            }

            if (type != null && (type.IsNullable || !type.IsValueType))
            {
                using (writer.Scope($"if ({element}.ValueKind == {typeof(JsonValueKind)}.Null)"))
                {
                    valueCallback(writer, w => w.Append($"null"));
                }
                using (writer.Scope($"else"))
                {
                    writer.DeserializeIntoVariable(serialization, valueCallback, element);
                }
            }
            else
            {
                writer.DeserializeIntoVariable(serialization, valueCallback, element);
            }
        }
        public static void WriteClientOptions(CodeWriter writer, BuildContext context)
        {
            var title = context.Configuration.LibraryName;

            using (writer.Scope($"namespace {context.Configuration.Namespace}"))
            {
                writer.WriteXmlDocumentationSummary($"Client options for {title}.");
                using (writer.Scope($"public class {title}ManagementClientOptions: {typeof(ClientOptions)}"))
                {
                }
            }
        }
예제 #5
0
 private void WriteConstructor(CodeWriter writer, ResponseHeaderGroupType responseHeaderGroup)
 {
     using (writer.Scope($"public {responseHeaderGroup.Declaration.Name}({typeof(Response)} {ResponseParameter})"))
     {
         writer.Line($"{ResponseField} = {ResponseParameter};");
     }
 }
예제 #6
0
        public void WriteClient(CodeWriter writer, Client client, Configuration configuration)
        {
            var cs         = client.Type;
            var @namespace = cs.Namespace;

            using (writer.Namespace(@namespace))
            {
                writer.WriteXmlDocumentationSummary(client.Description);
                using (writer.Scope($"{client.Declaration.Accessibility} partial class {cs.Name}"))
                {
                    WriteClientFields(writer, client);
                    WriteClientCtors(writer, client);

                    foreach (var clientMethod in client.Methods)
                    {
                        WriteClientMethod(writer, clientMethod, true);
                        WriteClientMethod(writer, clientMethod, false);
                    }

                    foreach (var pagingMethod in client.PagingMethods)
                    {
                        WritePagingOperation(writer, pagingMethod, true);
                        WritePagingOperation(writer, pagingMethod, false);
                    }

                    foreach (var longRunningOperation in client.LongRunningOperationMethods)
                    {
                        WriteStartOperationOperation(writer, longRunningOperation, true);
                        WriteStartOperationOperation(writer, longRunningOperation, false);
                    }
                }
            }
        }
예제 #7
0
 private void WriteJsonSerialize(CodeWriter writer, JsonSerialization jsonSerialization)
 {
     writer.Append($"void {typeof(IUtf8JsonSerializable)}.{nameof(IUtf8JsonSerializable.Write)}({typeof(Utf8JsonWriter)} writer)");
     using (writer.Scope())
     {
         writer.ToSerializeCall(jsonSerialization, w => w.AppendRaw("this"));
     }
     writer.Line();
 }
예제 #8
0
        private static void WriteConstructor(CodeWriter writer, ObjectType schema)
        {
            foreach (var constructor in schema.Constructors)
            {
                writer.WriteXmlDocumentationSummary($"Initializes a new instance of {schema.Declaration.Name}");
                foreach (var parameter in constructor.Parameters)
                {
                    writer.WriteXmlDocumentationParameter(parameter.Name, parameter.Description);
                }

                writer.Append($"{constructor.Declaration.Accessibility} {schema.Declaration.Name}(");
                foreach (var parameter in constructor.Parameters)
                {
                    writer.WriteParameter(parameter);
                }
                writer.RemoveTrailingComma();
                writer.Append($")");

                if (constructor.BaseConstructor?.Parameters.Length > 0)
                {
                    writer.Append($": base(");
                    foreach (var baseConstructorParameter in constructor.BaseConstructor.Parameters)
                    {
                        writer.Append($"{baseConstructorParameter.Name:I}, ");
                    }
                    writer.RemoveTrailingComma();
                    writer.Append($")");
                }

                writer.Line();

                using (writer.Scope())
                {
                    writer.WriteParameterNullChecks(constructor.Parameters);

                    foreach (var initializer in constructor.Initializers)
                    {
                        writer.Append($"{initializer.Property.Declaration.Name} = ")
                        .WriteReferenceOrConstant(initializer.Value)
                        .WriteConversion(initializer.Value.Type, initializer.Property.Declaration.Type);

                        if (initializer.DefaultValue != null &&
                            !initializer.Value.Type.IsValueType)
                        {
                            writer.Append($"?? ").WriteReferenceOrConstant(initializer.DefaultValue.Value);
                        }

                        writer.Line($";");
                    }
                }

                writer.Line();
            }
        }
예제 #9
0
        private static void DeserializeIntoVariable(this CodeWriter writer, JsonSerialization serialization, Action <CodeWriter, CodeWriterDelegate> valueCallback, CodeWriterDelegate element)
        {
            switch (serialization)
            {
            case JsonArraySerialization array:
                var arrayVariable = new CodeWriterDeclaration("array");
                writer.Line($"{array.Type} {arrayVariable:D} = new {array.Type}();");

                var collectionItemVariable = new CodeWriterDeclaration("item");
                using (writer.Scope($"foreach (var {collectionItemVariable:D} in {element}.EnumerateArray())"))
                {
                    writer.DeserializeValue(
                        array.ValueSerialization,
                        w => w.Append($"{collectionItemVariable}"),
                        (w, returnValue) => writer.Append($"{arrayVariable}.Add({returnValue});"));
                }

                valueCallback(writer, w => w.Append(arrayVariable));
                return;

            case JsonDictionarySerialization dictionary:
                var dictionaryVariable = new CodeWriterDeclaration("dictionary");
                writer.Line($"{dictionary.Type} {dictionaryVariable:D} = new {dictionary.Type}();");

                var dictionaryItemVariable = new CodeWriterDeclaration("property");
                using (writer.Scope($"foreach (var {dictionaryItemVariable:D} in {element}.EnumerateObject())"))
                {
                    writer.DeserializeValue(
                        dictionary.ValueSerialization,
                        w => w.Append($"{dictionaryItemVariable}.Value"),
                        (w, returnValue) => writer.Append($"{dictionaryVariable}.Add({dictionaryItemVariable}.Name, {returnValue});"));
                }

                valueCallback(writer, w => w.Append(dictionaryVariable));
                return;

            case JsonValueSerialization valueSerialization:
                valueCallback(writer, w => w.DeserializeValue(valueSerialization, element));
                return;
            }
        }
예제 #10
0
 private void WriteXmlDeserialize(CodeWriter writer, ObjectType model, XmlElementSerialization serialization)
 {
     using (writer.Scope($"internal static {model.Type} Deserialize{model.Declaration.Name}({typeof(XElement)} element)"))
     {
         writer.ToDeserializeCall(
             serialization,
             w => w.AppendRaw("element"),
             (w, v) => w.Line($"return {v};"),
             true);
     }
     writer.Line();
 }
예제 #11
0
        private void WriteSealedChoiceSerialization(CodeWriter writer, EnumType schema)
        {
            using (writer.Namespace(schema.Declaration.Namespace))
            {
                string declaredTypeName = schema.Declaration.Name;

                var isString = schema.BaseType.FrameworkType == typeof(string);

                using (writer.Scope($"internal static class {declaredTypeName}Extensions"))
                {
                    using (writer.Scope($"public static {schema.BaseType} ToSerialString(this {declaredTypeName} value) => value switch", end: "};"))
                    {
                        foreach (EnumTypeValue value in schema.Values)
                        {
                            writer.Line($"{declaredTypeName}.{value.Declaration.Name} => {value.Value.Value:L},");
                        }

                        writer.Line($"_ => throw new {typeof(ArgumentOutOfRangeException)}(nameof(value), value, \"Unknown {declaredTypeName} value.\")");
                    }
                    writer.Line();

                    using (writer.Scope($"public static {declaredTypeName} To{declaredTypeName}(this {schema.BaseType} value)"))
                    {
                        foreach (EnumTypeValue value in schema.Values)
                        {
                            writer.Append($"if ({schema.BaseType}.Equals(value, {value.Value.Value:L}");
                            if (isString)
                            {
                                writer.Append($", {typeof(StringComparison)}.InvariantCultureIgnoreCase");
                            }
                            writer.Line($")) return {declaredTypeName}.{value.Declaration.Name};");
                        }

                        writer.Line($"throw new {typeof(ArgumentOutOfRangeException)}(nameof(value), value, \"Unknown {declaredTypeName} value.\");");
                    }
                    writer.Line();
                }
            }
        }
예제 #12
0
        private void WriteStartOperationOperation(CodeWriter writer, LongRunningOperationMethod lroMethod, bool async)
        {
            RestClientMethod originalMethod = lroMethod.StartMethod;
            CSharpType       returnType     = async ? new CSharpType(typeof(Task <>), lroMethod.Operation.Type) : lroMethod.Operation.Type;

            Parameter[] parameters = originalMethod.Parameters;

            writer.WriteXmlDocumentationSummary(originalMethod.Description);

            foreach (Parameter parameter in parameters)
            {
                writer.WriteXmlDocumentationParameter(parameter.Name, parameter.Description);
            }
            writer.WriteXmlDocumentationParameter("cancellationToken", "The cancellation token to use.");

            string asyncText = async ? "async " : string.Empty;

            writer.Append($"public virtual {asyncText}{returnType} {CreateStartOperationName(lroMethod.Name, async)}(");
            foreach (Parameter parameter in parameters)
            {
                writer.WriteParameter(parameter);
            }
            writer.Line($"{typeof(CancellationToken)} cancellationToken = default)");

            using (writer.Scope())
            {
                writer.WriteParameterNullChecks(parameters);

                WriteDiagnosticScope(writer, lroMethod.Diagnostics, writer =>
                {
                    string awaitText     = async ? "await" : string.Empty;
                    string configureText = async ? ".ConfigureAwait(false)" : string.Empty;
                    writer.Append($"var originalResponse = {awaitText} RestClient.{CreateMethodName(originalMethod.Name, async)}(");
                    foreach (Parameter parameter in parameters)
                    {
                        writer.Append($"{parameter.Name}, ");
                    }

                    writer.Line($"cancellationToken){configureText};");

                    writer.Append($"return new {lroMethod.Operation.Type}({ClientDiagnosticsField}, {PipelineField}, RestClient.{CreateRequestMethodName(originalMethod.Name)}(");
                    foreach (Parameter parameter in parameters)
                    {
                        writer.Append($"{parameter.Name}, ");
                    }
                    writer.RemoveTrailingComma();
                    writer.Line($").Request, originalResponse);");
                });
            }
            writer.Line();
        }
예제 #13
0
        private void WriteClientCtors(CodeWriter writer, Client client)
        {
            writer.WriteXmlDocumentationSummary($"Initializes a new instance of {client.Type.Name} for mocking.");
            using (writer.Scope($"protected {client.Type.Name:D}()"))
            {
            }

            writer.WriteXmlDocumentationSummary($"Initializes a new instance of {client.Type.Name}");
            writer.WriteXmlDocumentationParameter(ClientDiagnosticsVariable, "The handler for diagnostic messaging in the client.");
            writer.WriteXmlDocumentationParameter(PipelineVariable, "The HTTP pipeline for sending and receiving REST requests and responses.");
            foreach (Parameter parameter in client.RestClient.Parameters)
            {
                writer.WriteXmlDocumentationParameter(parameter.Name, parameter.Description);
            }

            writer.Append($"internal {client.Type.Name:D}({typeof(ClientDiagnostics)} {ClientDiagnosticsVariable}, {typeof(HttpPipeline)} {PipelineVariable},");
            foreach (Parameter parameter in client.RestClient.Parameters)
            {
                writer.WriteParameter(parameter);
            }

            writer.RemoveTrailingComma();
            writer.Line($")");
            using (writer.Scope())
            {
                writer.Append($"this.RestClient = new {client.RestClient.Type}({ClientDiagnosticsVariable}, {PipelineVariable}, ");
                foreach (var parameter in client.RestClient.Parameters)
                {
                    writer.Append($"{parameter.Name}, ");
                }
                writer.RemoveTrailingComma();
                writer.Line($");");

                writer.Line($"{ClientDiagnosticsField} = {ClientDiagnosticsVariable};");
                writer.Line($"{PipelineField} = {PipelineVariable};");
            }
            writer.Line();
        }
예제 #14
0
        private void WriteXmlSerialize(CodeWriter writer, XmlElementSerialization serialization)
        {
            const string namehint = "nameHint";

            writer.Append($"void {typeof(IXmlSerializable)}.{nameof(IXmlSerializable.Write)}({typeof(XmlWriter)} writer, {typeof(string)} {namehint})");
            using (writer.Scope())
            {
                writer.ToSerializeCall(
                    serialization,
                    w => w.AppendRaw("this"),
                    null,
                    w => w.AppendRaw(namehint));
            }
            writer.Line();
        }
예제 #15
0
        public void WriteHeaderModel(CodeWriter writer, ResponseHeaderGroupType responseHeaderGroup)
        {
            using (writer.Namespace(responseHeaderGroup.Declaration.Namespace))
            {
                writer.UseNamespace(new CSharpType(typeof(ResponseHeadersExtensions)).Namespace);

                using (writer.Scope($"{responseHeaderGroup.Declaration.Accessibility} class {responseHeaderGroup.Declaration.Name}"))
                {
                    WriteField(writer);
                    WriteConstructor(writer, responseHeaderGroup);

                    foreach (var method in responseHeaderGroup.Headers)
                    {
                        WriteHeaderProperty(writer, method);
                    }
                }
            }
        }
예제 #16
0
        public static void WriteParameterNullChecks(this CodeWriter writer, IReadOnlyCollection <Parameter> parameters)
        {
            foreach (Parameter parameter in parameters)
            {
                if (parameter.DefaultValue != null && !CanBeInitializedInline(parameter))
                {
                    writer.Line($"{parameter.Name} ??= new {parameter.Type}({parameter.DefaultValue.Value.Value:L});");
                }
                else if (CanWriteNullCheck(parameter))
                {
                    using (writer.Scope($"if ({parameter.Name:I} == null)"))
                    {
                        writer.Line($"throw new {typeof(ArgumentNullException)}(nameof({parameter.Name:I}));");
                    }
                }
            }

            writer.Line();
        }
예제 #17
0
        private void WriteSealedChoiceSchema(CodeWriter writer, EnumType schema)
        {
            if (schema.Declaration.IsUserDefined)
            {
                return;
            }

            using (writer.Namespace(schema.Declaration.Namespace))
            {
                writer.WriteXmlDocumentationSummary(schema.Description);

                using (writer.Scope($"public enum {schema.Declaration.Name}"))
                {
                    foreach (EnumTypeValue value in schema.Values)
                    {
                        writer.WriteXmlDocumentationSummary(value.Description);
                        writer.Line($"{value.Declaration.Name},");
                    }
                    writer.RemoveTrailingComma();
                }
            }
        }
        public void WriteClient(CodeWriter writer, RestClient restClient)
        {
            var cs         = restClient.Type;
            var @namespace = cs.Namespace;

            using (writer.Namespace(@namespace))
            {
                writer.WriteXmlDocumentationSummary(restClient.Description);
                using (writer.Scope($"{restClient.Declaration.Accessibility} partial class {cs.Name}"))
                {
                    WriteClientFields(writer, restClient);

                    WriteClientCtor(writer, restClient, cs);

                    foreach (var method in restClient.Methods)
                    {
                        WriteRequestCreation(writer, method);
                        WriteOperation(writer, method, true);
                        WriteOperation(writer, method, false);
                    }
                }
            }
        }
        private void WriteClientCtor(CodeWriter writer, RestClient restClient, CSharpType cs)
        {
            writer.WriteXmlDocumentationSummary($"Initializes a new instance of {cs.Name}");
            writer.WriteXmlDocumentationParameter(ClientDiagnosticsVariable, "The handler for diagnostic messaging in the client.");
            writer.WriteXmlDocumentationParameter(PipelineVariable, "The HTTP pipeline for sending and receiving REST requests and responses.");
            foreach (Parameter parameter in restClient.Parameters)
            {
                writer.WriteXmlDocumentationParameter(parameter.Name, parameter.Description);
            }
            if (restClient.Parameters.HasAnyNullCheck())
            {
                writer.WriteXmlDocumentationException(typeof(ArgumentNullException), "This occurs when one of the required arguments is null.");
            }

            writer.Append($"public {cs.Name:D}({typeof(ClientDiagnostics)} {ClientDiagnosticsVariable}, {typeof(HttpPipeline)} {PipelineVariable},");
            foreach (Parameter clientParameter in restClient.Parameters)
            {
                writer.WriteParameter(clientParameter);
            }

            writer.RemoveTrailingComma();
            writer.Line($")");
            using (writer.Scope())
            {
                writer.WriteParameterNullChecks(restClient.Parameters);

                foreach (Parameter clientParameter in restClient.Parameters)
                {
                    writer.Line($"this.{clientParameter.Name} = {clientParameter.Name};");
                }

                writer.Line($"{ClientDiagnosticsField} = {ClientDiagnosticsVariable};");
                writer.Line($"{PipelineField} = {PipelineVariable};");
            }
            writer.Line();
        }
        private void WriteRequestCreation(CodeWriter writer, RestClientMethod clientMethod)
        {
            using var methodScope = writer.AmbientScope();

            var methodName = CreateRequestMethodName(clientMethod.Name);

            writer.Append($"internal {typeof(HttpMessage)} {methodName}(");
            var parameters = clientMethod.Parameters;

            foreach (Parameter clientParameter in parameters)
            {
                writer.Append($"{clientParameter.Type} {clientParameter.Name:D},");
            }
            writer.RemoveTrailingComma();
            writer.Line($")");
            using (writer.Scope())
            {
                var message = new CodeWriterDeclaration("message");
                var request = new CodeWriterDeclaration("request");
                var uri     = new CodeWriterDeclaration("uri");

                writer.Line($"var {message:D} = {PipelineField}.CreateMessage();");
                writer.Line($"var {request:D} = {message}.Request;");
                var method = clientMethod.Request.HttpMethod;
                writer.Line($"{request}.Method = {typeof(RequestMethod)}.{method.ToRequestMethodName()};");

                writer.Line($"var {uri:D} = new RawRequestUriBuilder();");
                foreach (var segment in clientMethod.Request.PathSegments)
                {
                    if (!segment.Value.IsConstant && segment.Value.Reference.Name == "nextLink")
                    {
                        if (segment.IsRaw)
                        {
                            // Artificial nextLink needs additional logic for relative versus absolute links
                            WritePathSegment(writer, uri, segment, "AppendRawNextLink");
                        }
                        else
                        {
                            // Natural nextLink parameters need to use a different method to parse path and query elements
                            WritePathSegment(writer, uri, segment, "AppendRaw");
                        }
                    }
                    else
                    {
                        WritePathSegment(writer, uri, segment);
                    }
                }

                //TODO: Duplicate code between query and header parameter processing logic
                foreach (var queryParameter in clientMethod.Request.Query)
                {
                    WriteQueryParameter(writer, uri, queryParameter);
                }

                writer.Line($"{request}.Uri = {uri};");

                foreach (var header in clientMethod.Request.Headers)
                {
                    WriteHeader(writer, request, header);
                }

                switch (clientMethod.Request.Body)
                {
                case SchemaRequestBody body:
                    using (WriteValueNullCheck(writer, body.Value))
                    {
                        WriteSerializeContent(
                            writer,
                            request,
                            body.Serialization,
                            w => WriteConstantOrParameter(w, body.Value, ignoreNullability: true));
                    }

                    break;

                case BinaryRequestBody binaryBody:
                    using (WriteValueNullCheck(writer, binaryBody.Value))
                    {
                        writer.Append($"{request}.Content = {typeof(RequestContent)}.Create(");
                        WriteConstantOrParameter(writer, binaryBody.Value);
                        writer.Line($");");
                    }
                    break;

                case TextRequestBody textBody:
                    using (WriteValueNullCheck(writer, textBody.Value))
                    {
                        writer.Append($"{request}.Content = new {typeof(StringRequestContent)}(");
                        WriteConstantOrParameter(writer, textBody.Value);
                        writer.Line($");");
                    }
                    break;

                case FlattenedSchemaRequestBody flattenedSchemaRequestBody:
                    var modelVariable = new CodeWriterDeclaration("model");
                    writer.Append($"var {modelVariable:D} = ")
                    .WriteInitialization(flattenedSchemaRequestBody.ObjectType, flattenedSchemaRequestBody.Initializers)
                    .Line($";");

                    WriteSerializeContent(
                        writer,
                        request,
                        flattenedSchemaRequestBody.Serialization,
                        w => w.Append(modelVariable));
                    break;

                case null:
                    break;

                default:
                    throw new NotImplementedException(clientMethod.Request.Body?.GetType().FullName);
                }

                writer.Line($"return {message};");
            }
            writer.Line();
        }
예제 #21
0
        private void WriteObjectSchema(CodeWriter writer, ObjectType schema)
        {
            using (writer.Namespace(schema.Declaration.Namespace))
            {
                List <CSharpType> implementsTypes = new List <CSharpType>();
                if (schema.Inherits != null)
                {
                    implementsTypes.Add(schema.Inherits);
                }

                if (schema.ImplementsDictionaryType != null)
                {
                    implementsTypes.Add(schema.ImplementsDictionaryType);
                }

                writer.WriteXmlDocumentationSummary(schema.Description);

                if (schema.IsStruct)
                {
                    writer.Append($"{schema.Declaration.Accessibility} readonly partial struct {schema.Declaration.Name}");
                }
                else
                {
                    writer.Append($"{schema.Declaration.Accessibility} partial class {schema.Declaration.Name}");
                }

                if (implementsTypes.Any())
                {
                    writer.AppendRaw(" : ");
                    foreach (var type in implementsTypes)
                    {
                        writer.Append($"{type} ,");
                    }
                    writer.RemoveTrailingComma();
                }

                writer.Line();
                using (writer.Scope())
                {
                    WriteConstructor(writer, schema);

                    foreach (var property in schema.Properties)
                    {
                        writer.WriteXmlDocumentationSummary(property.Description);

                        CSharpType propertyType = property.Declaration.Type;
                        writer.Append($"{property.Declaration.Accessibility} {propertyType} {property.Declaration.Name:D}");
                        writer.AppendRaw(property.IsReadOnly ? "{ get; }" : "{ get; set; }");

                        writer.Line();
                    }

                    if (schema.AdditionalPropertiesProperty is ObjectTypeProperty additionalPropertiesProperty)
                    {
                        var dictionaryType = schema.ImplementsDictionaryType;
                        Debug.Assert(dictionaryType != null);

                        var keyType                     = typeof(string);
                        var isReadonly                  = dictionaryType.FrameworkType == typeof(IReadOnlyDictionary <,>);
                        var itemType                    = dictionaryType.Arguments[1];
                        var keyValuePairType            = new CSharpType(typeof(KeyValuePair <,>), keyType, itemType);
                        var iEnumeratorKeyValuePairType = new CSharpType(typeof(IEnumerator <>), keyValuePairType);

                        var collectionType = isReadonly ? typeof(IReadOnlyCollection <>) : typeof(ICollection <>);

                        var iCollectionKeyValuePairType = new CSharpType(collectionType, keyValuePairType);

                        var keyValueCollectionType = isReadonly ? typeof(IEnumerable <>) : typeof(ICollection <>);
                        var iCollectionKeyType     = new CSharpType(keyValueCollectionType, keyType);
                        var iCollectionItemType    = new CSharpType(keyValueCollectionType, itemType);
                        var iEnumerator            = typeof(IEnumerator);
                        var iEnumerable            = typeof(IEnumerable);

                        string additionalProperties = additionalPropertiesProperty.Declaration.Name;

                        writer
                        .WriteXmlDocumentationInheritDoc()
                        .Line($"public {iEnumeratorKeyValuePairType} GetEnumerator() => {additionalProperties}.GetEnumerator();")
                        .WriteXmlDocumentationInheritDoc()
                        .Line($"{iEnumerator} {iEnumerable}.GetEnumerator() => {additionalProperties}.GetEnumerator();")
                        .WriteXmlDocumentationInheritDoc()
                        .Line($"public bool TryGetValue(string key, out {itemType} value) => {additionalProperties}.TryGetValue(key, out value);")
                        .WriteXmlDocumentationInheritDoc()
                        .Line($"public bool ContainsKey({keyType} key) => {additionalProperties}.ContainsKey(key);")
                        .WriteXmlDocumentationInheritDoc()
                        .Line($"public {iCollectionKeyType} Keys => {additionalProperties}.Keys;")
                        .WriteXmlDocumentationInheritDoc()
                        .Line($"public {iCollectionItemType} Values => {additionalProperties}.Values;")
                        .WriteXmlDocumentationInheritDoc()
                        .Line($"int {iCollectionKeyValuePairType}.Count => {additionalProperties}.Count;");

                        if (!isReadonly)
                        {
                            writer
                            .WriteXmlDocumentationInheritDoc()
                            .Line($"public void Add({keyType} key, {itemType} value) => {additionalProperties}.Add(key, value);")
                            .WriteXmlDocumentationInheritDoc()
                            .Line($"public bool Remove({keyType} key) => {additionalProperties}.Remove(key);")
                            .WriteXmlDocumentationInheritDoc()
                            .Line($"bool {iCollectionKeyValuePairType}.IsReadOnly => {additionalProperties}.IsReadOnly;")
                            .WriteXmlDocumentationInheritDoc()
                            .Line($"void {iCollectionKeyValuePairType}.Add({keyValuePairType} value) => {additionalProperties}.Add(value);")
                            .WriteXmlDocumentationInheritDoc()
                            .Line($"bool {iCollectionKeyValuePairType}.Remove({keyValuePairType} value) => {additionalProperties}.Remove(value);")
                            .WriteXmlDocumentationInheritDoc()
                            .Line($"bool {iCollectionKeyValuePairType}.Contains({keyValuePairType} value) => {additionalProperties}.Contains(value);")
                            .WriteXmlDocumentationInheritDoc()
                            .Line($"void {iCollectionKeyValuePairType}.CopyTo({keyValuePairType}[] destination, int offset) => {additionalProperties}.CopyTo(destination, offset);")
                            .WriteXmlDocumentationInheritDoc()
                            .Line($"void {iCollectionKeyValuePairType}.Clear() => {additionalProperties}.Clear();");
                        }

                        using (writer
                               .WriteXmlDocumentationInheritDoc()
                               .Scope($"public {itemType} this[{keyType} key]"))
                        {
                            writer.Line($"get => {additionalProperties}[key];");
                            if (!isReadonly)
                            {
                                writer.Line($"set => {additionalProperties}[key] = value;");
                            }
                        }
                    }
                }
            }
        }
예제 #22
0
        private static void DeserializeIntoVariableMayBeObject(this CodeWriter writer,
                                                               JsonSerialization serialization,
                                                               Action <CodeWriter, CodeWriterDelegate> valueCallback,
                                                               CodeWriterDelegate element,
                                                               Dictionary <ObjectTypeProperty, CodeWriterDeclaration>?propertyVariables = null)
        {
            if (serialization is JsonObjectSerialization obj)
            {
                var itemVariable = new CodeWriterDeclaration("property");

                if (propertyVariables == null)
                {
                    // this is the first level of object hierarchy
                    // collect all properties and initialize the dictionary
                    propertyVariables = new Dictionary <ObjectTypeProperty, CodeWriterDeclaration>();

                    CollectProperties(propertyVariables, obj);

                    foreach (var variable in propertyVariables)
                    {
                        var objectTypeProperty = variable.Key;
                        writer.Line($"{objectTypeProperty.Declaration.Type} {variable.Value:D} = default;");
                    }
                }

                var dictionaryVariable = new CodeWriterDeclaration("additionalPropertiesDictionary");

                var objAdditionalProperties = obj.AdditionalProperties;
                if (objAdditionalProperties != null)
                {
                    writer.Line($"{objAdditionalProperties.Type} {dictionaryVariable:D} = default;");
                }

                using (writer.Scope($"foreach (var {itemVariable:D} in {element}.EnumerateObject())"))
                {
                    foreach (JsonPropertySerialization property in obj.Properties)
                    {
                        CSharpType?type = property.Property?.Declaration.Type;

                        bool hasNullableType = type != null && type.IsNullable;

                        void WriteNullCheck()
                        {
                            using (writer.Scope($"if ({itemVariable.ActualName}.Value.ValueKind == {typeof(JsonValueKind)}.Null)"))
                            {
                                writer.Append($"continue;");
                            }
                        }

                        writer.Append($"if({itemVariable.ActualName}.NameEquals({property.Name:L}))");
                        using (writer.Scope())
                        {
                            if (hasNullableType)
                            {
                                WriteNullCheck();
                            }

                            if (property.Property != null)
                            {
                                // Reading a property value
                                writer.DeserializeIntoVariable(
                                    property.ValueSerialization,
                                    (w, v) => w.Line($"{propertyVariables[property.Property]} = {v};"),
                                    w => w.Append($"{itemVariable.ActualName}.Value"));
                            }
                            else
                            {
                                // Reading a nested object
                                writer.DeserializeIntoVariableMayBeObject(
                                    property.ValueSerialization,
                                    (w, v) => { },
                                    w => w.Append($"{itemVariable.ActualName}.Value"),
                                    propertyVariables);
                            }

                            writer.Line($"continue;");
                        }
                    }

                    if (objAdditionalProperties != null)
                    {
                        writer.Line($"{dictionaryVariable} ??= new {objAdditionalProperties.Type}();");
                        writer.DeserializeValue(
                            objAdditionalProperties.ValueSerialization,
                            w => w.Append($"{itemVariable}.Value"),
                            (w, v) => w.Line($"{dictionaryVariable}.Add({itemVariable}.Name, {v});"));
                    }
                }

                if (objAdditionalProperties != null)
                {
                    writer.Line($"{propertyVariables[objAdditionalProperties.Property]} = {dictionaryVariable};");
                }

                if (obj.Type != null)
                {
                    var initializers = new List <ObjectPropertyInitializer>();
                    foreach (var variable in propertyVariables)
                    {
                        var property = variable.Key;

                        initializers.Add(new ObjectPropertyInitializer(
                                             property,
                                             new Reference(variable.Value.ActualName, property.Declaration.Type)));
                    }

                    valueCallback(writer,
                                  w => w.WriteInitialization((ObjectType)obj.Type.Implementation, initializers));
                }
            }
            else
            {
                writer.DeserializeIntoVariableWithNullHandling(serialization, valueCallback, element);
            }
        }
예제 #23
0
        public static void ToSerializeCall(this CodeWriter writer, JsonSerialization serialization, CodeWriterDelegate name, CodeWriterDelegate?writerName = null)
        {
            writerName ??= w => w.AppendRaw("writer");

            switch (serialization)
            {
            case JsonArraySerialization array:
                writer.Line($"{writerName}.WriteStartArray();");
                var collectionItemVariable = new CodeWriterDeclaration("item");

                using (writer.Scope($"foreach (var {collectionItemVariable:D} in {name})"))
                {
                    writer.ToSerializeCall(
                        array.ValueSerialization,
                        w => w.Append(collectionItemVariable),
                        writerName);
                }

                writer.Line($"{writerName}.WriteEndArray();");
                return;

            case JsonDictionarySerialization dictionary:
                writer.Line($"{writerName}.WriteStartObject();");
                var dictionaryItemVariable = new CodeWriterDeclaration("item");

                using (writer.Scope($"foreach (var {dictionaryItemVariable:D} in {name})"))
                {
                    writer.Line($"{writerName}.WritePropertyName({dictionaryItemVariable}.Key);");
                    writer.ToSerializeCall(
                        dictionary.ValueSerialization,
                        w => w.Append($"{dictionaryItemVariable}.Value"),
                        writerName);
                }

                writer.Line($"{writerName}.WriteEndObject();");
                return;

            case JsonObjectSerialization obj:
                writer.Line($"{writerName}.WriteStartObject();");

                foreach (JsonPropertySerialization property in obj.Properties)
                {
                    bool hasNullableType  = property.Property?.Declaration.Type.IsNullable == true;
                    bool emptyAsUndefined = property.Property?.EmptyAsUndefined == true;

                    CodeWriter.CodeWriterScope?scope = default;
                    if (hasNullableType || emptyAsUndefined)
                    {
                        var propertyName = property.Property !.Declaration.Name;
                        writer.Append($"if (");
                        if (hasNullableType)
                        {
                            writer.Append($"{propertyName} != null");
                        }

                        if (emptyAsUndefined)
                        {
                            if (hasNullableType)
                            {
                                writer.Append($" && ");
                            }
                            writer.UseNamespace(typeof(Enumerable).Namespace !);
                            writer.Append($"{propertyName}.Any()");
                        }
                        writer.Append($")");
                        scope = writer.Scope();
                    }

                    using (scope)
                    {
                        writer.Line($"{writerName}.WritePropertyName({property.Name:L});");
                        writer.ToSerializeCall(
                            property.ValueSerialization,
                            w => w.Append($"{property.Property?.Declaration.Name}"));
                    }
                }

                if (obj.AdditionalProperties != null)
                {
                    var itemVariable = new CodeWriterDeclaration("item");

                    using (writer.Scope($"foreach (var {itemVariable:D} in {obj.AdditionalProperties.Property.Declaration.Name})"))
                    {
                        writer.Line($"{writerName}.WritePropertyName({itemVariable}.Key);");
                        writer.ToSerializeCall(
                            obj.AdditionalProperties.ValueSerialization,
                            w => w.Append($"{itemVariable}.Value"),
                            writerName);
                    }
                }

                writer.Line($"{writerName}.WriteEndObject();");
                return;

            case JsonValueSerialization valueSerialization:
                writer.UseNamespace(typeof(Utf8JsonWriterExtensions).Namespace !);

                if (valueSerialization.Type.IsFrameworkType)
                {
                    var frameworkType = valueSerialization.Type.FrameworkType;

                    if (frameworkType == typeof(JsonElement))
                    {
                        writer.Line($"{name}.WriteTo({writerName});");
                        return;
                    }

                    bool writeFormat = false;

                    writer.Append($"{writerName}.");
                    if (frameworkType == typeof(decimal) ||
                        frameworkType == typeof(double) ||
                        frameworkType == typeof(float) ||
                        frameworkType == typeof(long) ||
                        frameworkType == typeof(int) ||
                        frameworkType == typeof(short))
                    {
                        writer.AppendRaw("WriteNumberValue");
                    }
                    else if (frameworkType == typeof(object))
                    {
                        writer.AppendRaw("WriteObjectValue");
                    }
                    else if (frameworkType == typeof(string) ||
                             frameworkType == typeof(char) ||
                             frameworkType == typeof(Guid))
                    {
                        writer.AppendRaw("WriteStringValue");
                    }
                    else if (frameworkType == typeof(bool))
                    {
                        writer.AppendRaw("WriteBooleanValue");
                    }
                    else if (frameworkType == typeof(byte[]))
                    {
                        writer.AppendRaw("WriteBase64StringValue");
                        writeFormat = true;
                    }
                    else if (frameworkType == typeof(DateTimeOffset) ||
                             frameworkType == typeof(DateTime) ||
                             frameworkType == typeof(TimeSpan))
                    {
                        if (valueSerialization.Format == SerializationFormat.DateTime_Unix)
                        {
                            writer.AppendRaw("WriteNumberValue");
                        }
                        else
                        {
                            writer.AppendRaw("WriteStringValue");
                        }
                        writeFormat = true;
                    }

                    writer.Append($"({name}")
                    .AppendNullableValue(valueSerialization.Type);

                    if (writeFormat && valueSerialization.Format.ToFormatSpecifier() is string formatString)
                    {
                        writer.Append($", {formatString:L}");
                    }

                    writer.LineRaw(");");
                    return;
                }

                switch (valueSerialization.Type.Implementation)
                {
                case ObjectType _:
                    writer.Line($"{writerName}.WriteObjectValue({name});");
                    return;

                case EnumType clientEnum:
                    writer.Append($"{writerName}.WriteStringValue({name}")
                    .AppendNullableValue(valueSerialization.Type)
                    .AppendEnumToString(clientEnum)
                    .Line($");");
                    return;
                }

                throw new NotSupportedException();

            default:
                throw new NotSupportedException();
            }
        }
예제 #24
0
        public static void ToSerializeCall(this CodeWriter writer, XmlElementSerialization serialization, CodeWriterDelegate name, CodeWriterDelegate?writerName = null, CodeWriterDelegate?nameHint = null)
        {
            writerName ??= w => w.AppendRaw("writer");

            switch (serialization)
            {
            case XmlArraySerialization array:

                if (array.Wrapped)
                {
                    writer.Line($"{writerName}.WriteStartElement({array.Name:L});");
                }

                var itemVariable = new CodeWriterDeclaration("item");

                using (writer.Scope($"foreach (var {itemVariable:D} in {name})"))
                {
                    writer.ToSerializeCall(
                        array.ValueSerialization,
                        w => w.Append($"{itemVariable}"),
                        writerName);
                }

                if (array.Wrapped)
                {
                    writer.Line($"{writerName}.WriteEndElement();");
                }

                break;

            case XmlDictionarySerialization dictionarySerialization:
                var pairVariable = new CodeWriterDeclaration("pair");
                using (writer.Scope($"foreach (var {pairVariable:D} in {name})"))
                {
                    writer.ToSerializeCall(
                        dictionarySerialization.ValueSerialization,
                        w => w.Append($"{pairVariable}.Value"),
                        writerName);
                }

                break;

            case XmlObjectSerialization objectSerialization:
                if (nameHint != null)
                {
                    writer.Line($"{writerName}.WriteStartElement({nameHint} ?? {objectSerialization.Name:L});");
                }
                else
                {
                    writer.Line($"{writerName}.WriteStartElement({objectSerialization.Name:L});");
                }

                CodeWriter.CodeWriterScope?CheckPropertyForNull(ObjectTypeProperty objectTypeProperty)
                {
                    return(objectTypeProperty.Declaration.Type.IsNullable ? writer.Scope($"if ({objectTypeProperty.Declaration.Name} != null)") : default);
                }

                foreach (XmlObjectAttributeSerialization property in objectSerialization.Attributes)
                {
                    using (CheckPropertyForNull(property.Property))
                    {
                        writer.Line($"{writerName}.WriteStartAttribute({property.Name:L});");
                        writer.ToSerializeValueCall(
                            w => w.Append($"{property.Property.Declaration.Name}"),
                            writerName,
                            property.ValueSerialization);
                        writer.Line($"{writerName}.WriteEndAttribute();");
                    }
                }

                foreach (XmlObjectElementSerialization property in objectSerialization.Elements)
                {
                    using (CheckPropertyForNull(property.Property))
                    {
                        writer.ToSerializeCall(
                            property.ValueSerialization,
                            w => w.Append($"{property.Property.Declaration.Name}"));
                    }
                }

                foreach (XmlObjectArraySerialization property in objectSerialization.EmbeddedArrays)
                {
                    using (CheckPropertyForNull(property.Property))
                    {
                        writer.ToSerializeCall(
                            property.ArraySerialization,
                            w => w.Append($"{property.Property.Declaration.Name}"));
                    }
                }

                writer.Line($"{writerName}.WriteEndElement();");
                return;
        public static void WriteAggregateClient(CodeWriter writer, BuildContext context)
        {
            var title = context.Configuration.LibraryName;

            using (writer.Scope($"namespace {context.Configuration.Namespace}"))
            {
                Dictionary <string, Parameter> allParameters = new Dictionary <string, Parameter>();
                foreach (var parameter in context.Library.Clients.SelectMany(p => p.RestClient.Parameters))
                {
                    if (ManagementClientWriterHelpers.IsApiVersionParameter(parameter))
                    {
                        continue;
                    }

                    allParameters[parameter.Name] = parameter;
                }

                writer.WriteXmlDocumentationSummary($"{title} service management client.");
                using (writer.Scope($"public class {title}ManagementClient"))
                {
                    writer.Line($"private readonly {typeof(ClientDiagnostics)}  {ClientDiagnosticsField};");
                    writer.Line($"private readonly {typeof(HttpPipeline)} {PipelineField};");
                    foreach (var parameter in allParameters.Values)
                    {
                        writer.Line($"private readonly {parameter.Type} _{parameter.Name};");
                    }

                    writer.Line();

                    writer.WriteXmlDocumentationSummary($"Initializes a new instance of {title}ManagementClient for mocking.");
                    using (writer.Scope($"protected {title}ManagementClient()"))
                    {
                    }
                    writer.Line();


                    writer.WriteXmlDocumentationSummary($"Initializes a new instance of {title}ManagementClient");
                    foreach (Parameter parameter in allParameters.Values)
                    {
                        if (ManagementClientWriterHelpers.IsEndpointParameter(parameter))
                        {
                            continue;
                        }
                        writer.WriteXmlDocumentationParameter(parameter.Name, parameter.Description);
                    }
                    writer.WriteXmlDocumentationParameter(TokenCredentialVariable, "The OAuth token for making client requests.");
                    writer.WriteXmlDocumentationParameter(OptionsVariable, "The options for configuring the client.");

                    writer.Append($"public {title}ManagementClient(");
                    foreach (Parameter parameter in allParameters.Values)
                    {
                        if (ManagementClientWriterHelpers.IsEndpointParameter(parameter))
                        {
                            continue;
                        }

                        writer.WriteParameter(parameter);
                    }

                    writer.Append($"{typeof(TokenCredential)} {TokenCredentialVariable}, {title}ManagementClientOptions {OptionsVariable} = null) : this(");
                    foreach (Parameter parameter in allParameters.Values)
                    {
                        // Pass the default host
                        if (ManagementClientWriterHelpers.IsEndpointParameter(parameter))
                        {
                            writer.Append($"null, ");
                            continue;
                        }

                        writer.Append($"{parameter.Name},");
                    }

                    writer.Line($"{TokenCredentialVariable}, {OptionsVariable})");
                    using (writer.Scope())
                    {
                    }

                    writer.WriteXmlDocumentationSummary($"Initializes a new instance of {title}ManagementClient");
                    foreach (Parameter parameter in allParameters.Values)
                    {
                        writer.WriteXmlDocumentationParameter(parameter.Name, parameter.Description);
                    }
                    writer.WriteXmlDocumentationParameter(TokenCredentialVariable, "The OAuth token for making client requests.");
                    writer.WriteXmlDocumentationParameter(OptionsVariable, "The options for configuring the client.");
                    if (allParameters.Values.HasAnyNullCheck())
                    {
                        writer.WriteXmlDocumentationException(typeof(ArgumentNullException), "This occurs when one of the required arguments is null.");
                    }

                    writer.Append($"public {title}ManagementClient(");
                    foreach (Parameter parameter in allParameters.Values)
                    {
                        writer.WriteParameter(parameter, false);
                    }

                    writer.Append($"{typeof(TokenCredential)} {TokenCredentialVariable}, {title}ManagementClientOptions {OptionsVariable} = null)");

                    using (writer.Scope())
                    {
                        writer.WriteParameterNullChecks(allParameters.Values);

                        writer.Line($"{OptionsVariable} ??= new {title}ManagementClientOptions();");
                        writer.Line($"{ClientDiagnosticsField} = new {typeof(ClientDiagnostics)}({OptionsVariable});");
                        writer.Line($"{PipelineField} = {typeof(ManagementPipelineBuilder)}.Build({TokenCredentialVariable}, endpoint, {OptionsVariable});");

                        foreach (Parameter parameter in allParameters.Values)
                        {
                            writer.Line($"_{parameter.Name} = {parameter.Name};");
                        }
                    }
                    writer.Line();

                    foreach (var client in context.Library.Clients)
                    {
                        writer.WriteXmlDocumentationSummary($"Creates a new instance of {client.Type.Name}");
                        using (writer.Scope($"public virtual {client.Type} Get{client.Type.Name}()"))
                        {
                            writer.Append($"return new {client.Type}({ClientDiagnosticsField}, {PipelineField}, ");
                            foreach (var parameter in client.RestClient.Parameters)
                            {
                                if (ManagementClientWriterHelpers.IsApiVersionParameter(parameter))
                                {
                                    continue;
                                }

                                writer.Append($"_{parameter.Name}, ");
                            }
                            writer.RemoveTrailingComma();
                            writer.Line($");");
                        }

                        writer.Line();
                    }
                }
            }
        }
예제 #26
0
        public static void Write(CodeWriter writer, LongRunningOperation operation)
        {
            var responseVariable = "response";

            void WriteResultFunction(bool async)
            {
                if (operation.ResultSerialization != null)
                {
                    writer.WriteDeserializationForMethods(
                        operation.ResultSerialization,
                        async: async,
                        (w, v) => w.Line($"return {v};"),
                        responseVariable);
                }
                else
                {
                    if (async)
                    {
                        writer.Line($"return await new {typeof(ValueTask<Response>)}({responseVariable}).ConfigureAwait(false);");
                    }
                    else
                    {
                        writer.Line($"return {responseVariable};");
                    }
                }
            }

            var cs         = operation.Type;
            var @namespace = cs.Namespace;

            using (writer.Namespace(@namespace))
            {
                writer.WriteXmlDocumentationSummary(operation.Description);
                var interfaceType         = new CSharpType(typeof(IOperationSource <>), operation.ResultType);
                var baseType              = new CSharpType(typeof(Operation <>), operation.ResultType);
                var waitForCompletionType = new CSharpType(typeof(ValueTask <>), new CSharpType(typeof(Response <>), operation.ResultType));
                var helperType            = new CSharpType(typeof(ArmOperationHelpers <>), operation.ResultType);

                using (writer.Scope($"{operation.Declaration.Accessibility} partial class {cs.Name}: {baseType}, {interfaceType}"))
                {
                    writer.Line($"private readonly {helperType} _operation;");

                    using (writer.Scope($"internal {cs.Name}({typeof(ClientDiagnostics)} clientDiagnostics, {typeof(HttpPipeline)} pipeline, {typeof(Request)} request, {typeof(Response)} response)"))
                    {
                        writer.Line($"_operation = new {helperType}(this, clientDiagnostics, pipeline, request, response, {typeof(OperationFinalStateVia)}.{operation.FinalStateVia}, {operation.Diagnostics.ScopeName:L});");
                    }

                    writer.WriteXmlDocumentationInheritDoc();
                    writer.Line($"public override string Id => _operation.Id;");
                    writer.Line();

                    writer.WriteXmlDocumentationInheritDoc();
                    writer.Line($"public override {operation.ResultType} Value => _operation.Value;");
                    writer.Line();

                    writer.WriteXmlDocumentationInheritDoc();
                    writer.Line($"public override bool HasCompleted => _operation.HasCompleted;");
                    writer.Line();

                    writer.WriteXmlDocumentationInheritDoc();
                    writer.Line($"public override bool HasValue => _operation.HasValue;");
                    writer.Line();

                    writer.WriteXmlDocumentationInheritDoc();
                    writer.Line($"public override {typeof(Response)} GetRawResponse() => _operation.GetRawResponse();");
                    writer.Line();

                    writer.WriteXmlDocumentationInheritDoc();
                    writer.Line($"public override {typeof(Response)} UpdateStatus({typeof(CancellationToken)} cancellationToken = default) => _operation.UpdateStatus(cancellationToken);");
                    writer.Line();

                    writer.WriteXmlDocumentationInheritDoc();
                    writer.Line($"public override {typeof(ValueTask<Response>)} UpdateStatusAsync({typeof(CancellationToken)} cancellationToken = default) => _operation.UpdateStatusAsync(cancellationToken);");
                    writer.Line();

                    writer.WriteXmlDocumentationInheritDoc();
                    writer.Line($"public override {waitForCompletionType} WaitForCompletionAsync({typeof(CancellationToken)} cancellationToken = default) => _operation.WaitForCompletionAsync(cancellationToken);");
                    writer.Line();

                    writer.WriteXmlDocumentationInheritDoc();
                    writer.Line($"public override {waitForCompletionType} WaitForCompletionAsync({typeof(TimeSpan)} pollingInterval, {typeof(CancellationToken)} cancellationToken = default) => _operation.WaitForCompletionAsync(pollingInterval, cancellationToken);");
                    writer.Line();

                    using (writer.Scope($"{operation.ResultType} {interfaceType}.CreateResult({typeof(Response)} {responseVariable:D}, {typeof(CancellationToken)} cancellationToken)"))
                    {
                        WriteResultFunction(false);
                    }
                    writer.Line();

                    using (writer.Scope($"async {new CSharpType(typeof(ValueTask<>), operation.ResultType)} {interfaceType}.CreateResultAsync({typeof(Response)} {responseVariable:D}, {typeof(CancellationToken)} cancellationToken)"))
                    {
                        WriteResultFunction(true);
                    }
                }
            }
        }
예제 #27
0
        private void WriteClientMethod(CodeWriter writer, ClientMethod clientMethod, bool async)
        {
            CSharpType?bodyType     = clientMethod.RestClientMethod.ReturnType;
            CSharpType responseType = bodyType != null ?
                                      new CSharpType(typeof(Response <>), bodyType) :
                                      typeof(Response);

            responseType = async ? new CSharpType(typeof(Task <>), responseType) : responseType;

            var parameters = clientMethod.RestClientMethod.Parameters;

            writer.WriteXmlDocumentationSummary(clientMethod.Description);

            foreach (Parameter parameter in parameters)
            {
                writer.WriteXmlDocumentationParameter(parameter.Name, parameter.Description);
            }

            writer.WriteXmlDocumentationParameter("cancellationToken", "The cancellation token to use.");

            var methodName = CreateMethodName(clientMethod.Name, async);
            var asyncText  = async ? "async" : string.Empty;

            writer.Append($"public virtual {asyncText} {responseType} {methodName}(");

            foreach (Parameter parameter in parameters)
            {
                writer.WriteParameter(parameter);
            }
            writer.Line($"{typeof(CancellationToken)} cancellationToken = default)");

            using (writer.Scope())
            {
                WriteDiagnosticScope(writer, clientMethod.Diagnostics, writer =>
                {
                    writer.Append($"return (");
                    if (async)
                    {
                        writer.Append($"await ");
                    }

                    writer.Append($"RestClient.{CreateMethodName(clientMethod.RestClientMethod.Name, async)}(");
                    foreach (var parameter in clientMethod.RestClientMethod.Parameters)
                    {
                        writer.Append($"{parameter.Name:I}, ");
                    }
                    writer.Append($"cancellationToken)");

                    if (async)
                    {
                        writer.Append($".ConfigureAwait(false)");
                    }

                    writer.Append($")");

                    if (bodyType == null && clientMethod.RestClientMethod.HeaderModel != null)
                    {
                        writer.Append($".GetRawResponse()");
                    }

                    writer.Line($";");
                });
            }

            writer.Line();
        }
예제 #28
0
        public static CodeWriter WriteInitialization(this CodeWriter writer, ObjectType objectType, IEnumerable <ObjectPropertyInitializer> initializers)
        {
            ObjectPropertyInitializer?FindInitializerForParameter(ObjectTypeConstructor constructor, Parameter constructorParameter)
            {
                var property = constructor.FindPropertyInitializedByParameter(constructorParameter);

                return(initializers.SingleOrDefault(i => i.Property == property));
            }

            // Checks if constructor parameters can be satisfied by the provided initializer list
            List <ObjectPropertyInitializer>?TryGetParameters(ObjectTypeConstructor constructor)
            {
                List <ObjectPropertyInitializer> constructorInitializers = new List <ObjectPropertyInitializer>();

                foreach (var constructorParameter in constructor.Parameters)
                {
                    var objectPropertyInitializer = FindInitializerForParameter(constructor, constructorParameter);
                    if (objectPropertyInitializer == null)
                    {
                        return(null);
                    }

                    constructorInitializers.Add(objectPropertyInitializer);
                }

                return(constructorInitializers);
            }

            // Find longest satisfiable ctor
            List <ObjectPropertyInitializer>?selectedCtorInitializers = null;

            foreach (var constructor in objectType.Constructors)
            {
                var newInitializers = TryGetParameters(constructor);
                if (newInitializers != null &&
                    newInitializers.Count > (selectedCtorInitializers?.Count ?? -1))
                {
                    selectedCtorInitializers = newInitializers;
                }
            }

            Debug.Assert(selectedCtorInitializers != null);

            writer.Append($"new {objectType.Type}(");
            foreach (var initializer in selectedCtorInitializers)
            {
                writer.WriteReferenceOrConstant(initializer.Value);
                writer.WriteConversion(initializer.Value.Type, initializer.Property.Declaration.Type);
                writer.Append($", ");
            }
            writer.RemoveTrailingComma();
            writer.Append($")");

            // Find properties that would have to be initialized via property initializers
            var restOfInitializers = initializers.Except(selectedCtorInitializers).ToArray();

            if (restOfInitializers.Any())
            {
                using (writer.Scope($"", newLine: false))
                {
                    foreach (var propertyInitializer in restOfInitializers)
                    {
                        writer.Append($"{propertyInitializer.Property.Declaration.Name} = ")
                        .WriteReferenceOrConstant(propertyInitializer.Value);

                        writer.WriteConversion(propertyInitializer.Value.Type, propertyInitializer.Property.Declaration.Type);

                        writer.Line($",");
                    }

                    writer.RemoveTrailingComma();
                }
            }

            return(writer);
        }
예제 #29
0
        private void WriteObjectSerialization(CodeWriter writer, ObjectType model)
        {
            if (!model.Serializations.Any())
            {
                return;
            }

            using (writer.Namespace(model.Declaration.Namespace))
            {
                if (model.IsStruct)
                {
                    writer.Append($"{model.Declaration.Accessibility} partial struct {model.Declaration.Name}");
                }
                else
                {
                    writer.Append($"{model.Declaration.Accessibility} partial class {model.Declaration.Name}");
                }

                if (model.IncludeSerializer)
                {
                    bool hasJson = model.Serializations.OfType <JsonSerialization>().Any();
                    bool hasXml  = model.Serializations.OfType <XmlElementSerialization>().Any();
                    if (hasJson || hasXml)
                    {
                        writer.Append($": ");
                    }

                    if (hasJson)
                    {
                        writer.Append($"{typeof(IUtf8JsonSerializable)}");
                        writer.Append($", ");
                    }

                    if (hasXml)
                    {
                        writer.Append($"{typeof(IXmlSerializable)}");
                        writer.Append($", ");
                    }

                    writer.RemoveTrailingComma();
                }

                using (writer.Scope())
                {
                    foreach (var serialization in model.Serializations)
                    {
                        switch (serialization)
                        {
                        case JsonSerialization jsonSerialization:
                            if (model.IncludeSerializer)
                            {
                                WriteJsonSerialize(writer, jsonSerialization);
                            }

                            if (model.IncludeDeserializer)
                            {
                                WriteJsonDeserialize(writer, model, jsonSerialization);
                            }

                            break;

                        case XmlElementSerialization xmlSerialization:
                            if (model.IncludeSerializer)
                            {
                                WriteXmlSerialize(writer, xmlSerialization);
                            }

                            if (model.IncludeDeserializer)
                            {
                                WriteXmlDeserialize(writer, model, xmlSerialization);
                            }

                            break;

                        default:
                            throw new NotImplementedException(serialization.ToString());
                        }
                    }
                }
            }
        }
예제 #30
0
        private void WritePagingOperation(CodeWriter writer, PagingMethod pagingMethod, bool async)
        {
            var        pageType     = pagingMethod.ItemType;
            CSharpType responseType = async ? new CSharpType(typeof(AsyncPageable <>), pageType) : new CSharpType(typeof(Pageable <>), pageType);
            var        parameters   = pagingMethod.Method.Parameters;

            writer.WriteXmlDocumentationSummary(pagingMethod.Method.Description);

            foreach (Parameter parameter in parameters)
            {
                writer.WriteXmlDocumentationParameter(parameter.Name, parameter.Description);
            }

            writer.WriteXmlDocumentationParameter("cancellationToken", "The cancellation token to use.");

            writer.Append($"public virtual {responseType} {CreateMethodName(pagingMethod.Name, async)}(");
            foreach (Parameter parameter in parameters)
            {
                writer.WriteParameter(parameter);
            }

            writer.Line($"{typeof(CancellationToken)} cancellationToken = default)");

            using (writer.Scope())
            {
                writer.WriteParameterNullChecks(parameters);

                var pageWrappedType = new CSharpType(typeof(Page <>), pageType);
                var funcType        = async ? new CSharpType(typeof(Task <>), pageWrappedType) : pageWrappedType;
                var nullableInt     = new CSharpType(typeof(int), true);

                var continuationTokenText = pagingMethod.NextLinkName != null ? $"response.Value.{pagingMethod.NextLinkName}" : "null";
                var asyncText             = async ? "async" : string.Empty;
                var awaitText             = async ? "await" : string.Empty;
                var configureAwaitText    = async ? ".ConfigureAwait(false)" : string.Empty;
                using (writer.Scope($"{asyncText} {funcType} FirstPageFunc({nullableInt} pageSizeHint)"))
                {
                    WriteDiagnosticScope(writer, pagingMethod.Diagnostics, writer =>
                    {
                        writer.Append($"var response = {awaitText} RestClient.{CreateMethodName(pagingMethod.Method.Name, async)}(");
                        foreach (Parameter parameter in parameters)
                        {
                            writer.Append($"{parameter.Name}, ");
                        }

                        writer.Line($"cancellationToken){configureAwaitText};");
                        writer.Line($"return {typeof(Page)}.FromValues(response.Value.{pagingMethod.ItemName}, {continuationTokenText}, response.GetRawResponse());");
                    });
                }

                var nextPageFunctionName = "null";
                if (pagingMethod.NextPageMethod != null)
                {
                    nextPageFunctionName = "NextPageFunc";
                    var nextPageParameters = pagingMethod.NextPageMethod.Parameters;
                    using (writer.Scope($"{asyncText} {funcType} {nextPageFunctionName}({typeof(string)} nextLink, {nullableInt} pageSizeHint)"))
                    {
                        WriteDiagnosticScope(writer, pagingMethod.Diagnostics, writer =>
                        {
                            writer.Append($"var response = {awaitText} RestClient.{CreateMethodName(pagingMethod.NextPageMethod.Name, async)}(");
                            foreach (Parameter parameter in nextPageParameters)
                            {
                                writer.Append($"{parameter.Name}, ");
                            }
                            writer.Line($"cancellationToken){configureAwaitText};");
                            writer.Line($"return {typeof(Page)}.FromValues(response.Value.{pagingMethod.ItemName}, {continuationTokenText}, response.GetRawResponse());");
                        });
                    }
                }
                writer.Line($"return {typeof(PageableHelpers)}.Create{(async ? "Async" : string.Empty)}Enumerable(FirstPageFunc, {nextPageFunctionName});");
            }
            writer.Line();
        }