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;"); } }
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(); }
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)}")) { } } }
private void WriteConstructor(CodeWriter writer, ResponseHeaderGroupType responseHeaderGroup) { using (writer.Scope($"public {responseHeaderGroup.Declaration.Name}({typeof(Response)} {ResponseParameter})")) { writer.Line($"{ResponseField} = {ResponseParameter};"); } }
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); } } } }
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(); }
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(); } }
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; } }
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(); }
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(); } } }
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(); }
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(); }
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(); }
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); } } } }
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(); }
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(); }
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;"); } } } } } }
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); } }
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(); } }
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(); } } } }
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); } } } }
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(); }
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); }
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()); } } } } }
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(); }