<#@ template language="C#" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.IO" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="ServiceClientGenerator.DefaultConfiguration" #> <#+ // An object that contains all the information about a service public ServiceConfiguration Config { get; set; } /// /// Model representing the default configuration modes as built /// from the sdk-default-configurations.json file. /// public DefaultConfigurationModel DefaultConfigurationModel { get; set; } // Adds the Amazon Apache 2.0 license public void AddLicenseHeader() { #> /* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ /* * Do not modify this file. This file is generated from the <#= Path.GetFileName(this.Config.ModelPath) #> service model. */ <#+ } // Adds documentation to the begin operation based on the name public void AddBeginAsyncDocumentation(Operation operation) { #> /// /// Initiates the asynchronous execution of the <#=operation.Name#> operation. /// /// /// Container for the necessary parameters to execute the <#=operation.Name#> operation on Amazon<#=this.Config.ClassName#>Client. /// An AsyncCallback delegate that is invoked when the operation completes. /// A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback /// procedure using the AsyncState property. /// /// An IAsyncResult that can be used to poll or wait for results, or both; this value is also needed when invoking End<#=operation.Name#> /// operation. <#+ if(!string.IsNullOrEmpty(operation.RestAPIDocUrl)) { #> /// REST API Reference for <#=operation.Name#> Operation <#+ } } // Generates the end operation async documentation public void AddEndAsyncDocumentation(Operation operation) { #> /// /// Finishes the asynchronous execution of the <#=operation.Name#> operation. /// /// /// The IAsyncResult returned by the call to Begin<#=operation.Name#>. /// /// Returns a <#=operation.Name#>Result from <#=this.Config.ClassName#>. <#+ if(!string.IsNullOrEmpty(operation.RestAPIDocUrl)) { #> /// REST API Reference for <#=operation.Name#> Operation <#+ } } // Generates Client documentation public void FormatServiceClientDocumentation(string documentation) { documentation = CleanupDocumentation(documentation); #> /// /// Implementation for accessing <#= this.Config.ClassName #> /// <#+ WriteCommentBlock(" ", documentation); #> /// <#+ } // Generates interface documentation public void FormatServiceInterfaceDocumentation(string documentation) { documentation = CleanupDocumentation(documentation); #> /// /// Interface for accessing <#= this.Config.ClassName #> /// <#+ WriteCommentBlock(" ", documentation); #> /// <#+ } // Adds documentation to the class based on the shape public void FormatClassDocumentation(Shape structure) { if(structure == null) { #> /// /// Empty class reserved for future use. /// <#+ return; } var documentation = CleanupDocumentation(structure.Documentation); #> /// <#+ WriteCommentBlock(" ", documentation); #> /// <#+ } // Adds documentation to the members of a structure public void FormatPropertyDocumentation(Member member, string documentationPreface = "") { if (documentationPreface != null && documentationPreface != "") { if (!documentationPreface.EndsWith(".")) { documentationPreface += "."; } documentationPreface = "

" + documentationPreface + "

"; } var documentation = CleanupDocumentation(string.Format("Gets and sets the property {0}. {1}{2}", member.PropertyName, documentationPreface, member.Documentation)); #> /// <#+ WriteCommentBlock(" ", documentation); #> /// <#+ } public void FormatOperationDocumentationSync(Operation operation, bool includeRequest) { FormatOperationDocumentationHelper(operation, includeRequest, false); } public void FormatOperationDocumentationAsync(Operation operation, bool includeRequest) { FormatOperationDocumentationHelper(operation, includeRequest, true); } // Documents the operation in a client or interface and optionally includes request param private void FormatOperationDocumentationHelper(Operation operation, bool includeRequest, bool isAsync) { var documentation = CleanupDocumentation(operation.Documentation); #> /// <#+ WriteCommentBlock(" ", documentation); #> /// <#+ if (includeRequest) { #> /// Container for the necessary parameters to execute the <#=operation.Name#> service method. <#+ } if (isAsync) { // follows Async Pattern #> /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. /// <#+ } #> /// /// The response from the <#=operation.Name#> service method, as returned by <#=this.Config.ClassName#>. <#+ // Skip adding exceptions in the ndoc because we are not generating exceptions from the service model. if(this.Config.Namespace != "Amazon.S3") { foreach(var exception in operation.Exceptions) { this.FormatExceptionDocumentation(exception); } } if(!string.IsNullOrEmpty(operation.RestAPIDocUrl)) { #> /// REST API Reference for <#=operation.Name#> Operation <#+ } } // Generates operation documentation with a param tag for each member in the list public void FormatOperationDocumentation(Operation operation, List members, bool isSync) { var documentation = CleanupDocumentation(operation.Documentation); #> /// <#+ WriteCommentBlock(" ", documentation); #> /// <#+ foreach(var item in members) { #> /// <#=item.GetParamDocumentationForOperation(operation.Name)#> <#+ } if (!isSync) { #> /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. /// <#+ } #> /// /// The response from the <#=operation.Name#> service method, as returned by <#=this.Config.ClassName#>. <#+ if (!this.Config.ServiceModel.Customizations.SuppressSimpleMethodExceptionDocs) { foreach(var exception in operation.Exceptions) { this.FormatExceptionDocumentation(exception); } } if(!string.IsNullOrEmpty(operation.RestAPIDocUrl)) { #> /// REST API Reference for <#=operation.Name#> Operation <#+ } } public void FormatOperationRequestDocumentation(Operation operation) { var documentation = CleanupDocumentation(operation.Documentation); #> /// /// Container for the parameters to the <#=operation.Name#> operation. <#+ WriteCommentBlock(" ", documentation); #> /// <#+ } // Generates documentation for an exception, added to operation documentation public void FormatExceptionDocumentation(ExceptionShape exceptionShape) { var documentation = CleanupDocumentation(exceptionShape.Documentation); #> /// <#+ WriteCommentBlock(" ", documentation); #> /// <#+ } // Generates documentation for a result that is empty public void FormatVoidResultDocumentation(string operationName) { #> /// /// Returns information about the <#=operationName#> response metadata. /// The <#=operationName#> operation has a void result type. /// <#+ } // Writes a block for an xml comment with correct line endings // Every \n (new line) in the block is written on a new line of the block private void WriteCommentBlock(string spaceBlock, string block) { foreach(var line in block.Split('\n')) { this.Write("{0}/// {1}\r\n", spaceBlock, line); } } // Removes unneccesary tags from the documentation and formats paragraph tags correctly public string CleanupDocumentation(string documentation) { documentation = documentation .Replace("\r", "") .Replace("\n", "") .Replace("
", "") .Replace("

", "\n\n") .Replace("

", "\n\n") .Replace("", "") .Replace("", "") .Replace("", "") .Replace("","") .Replace("

","") .Trim(); // Remove examples because these will be wire protocol examples documentation = RemoveSnippets(documentation, "", ""); // Remove commented out documentation documentation = RemoveSnippets(documentation, ""); documentation = RemoveSnippets(documentation, ""); documentation = RemoveSnippets(documentation, ""); documentation = RemoveSnippets(documentation, ""); documentation = RemoveSnippets(documentation, ""); // Remove the first para tags since it just be the first paragraph in the summary. // This also helps clean up documentation that only contains one para block. if(documentation.StartsWith("")) { int closePos= documentation.IndexOf(""); if (closePos < 0) // note: documentation was transformed a few lines above throw new Exception("Documentation is missing closing tag (ie

or ): " + documentation); var firstParaContent= documentation.Substring("".Length, closePos - "".Length); documentation = firstParaContent + documentation.Substring(closePos + "".Length); } // Insert line breaks around 80 character line length StringBuilder sb = new StringBuilder(); int position = 0; int currentLineLength = 0; while(position < documentation.Length) { char c = documentation[position]; if(c == '\n') { currentLineLength = 0; sb.Append(c); } else if(c == ' ' && currentLineLength > 80) { currentLineLength = 0; sb.Append("\n"); } else { currentLineLength++; sb.Append(c); } position++; } return sb.ToString().Trim(); } private string RemoveSnippets(string documentation, string startToken, string endToken) { int startPos = documentation.IndexOf(startToken); while(startPos != -1) { int closePos = documentation.IndexOf(endToken, startPos); documentation = documentation.Substring(0, startPos) + documentation.Substring(closePos + endToken.Length); startPos = documentation.IndexOf(startToken); } return documentation; } // Generates the comment block for simple constructors, each member is added as a param tag with the shape's documentation or // a generic comment if no documentation is found public void FormatSimpleConstructorDocumentation(string className, IList members) { #> /// /// Instantiates <#=className#> with the parameterized properties /// <#+ foreach (var member in members) { #> /// <#=member.GetParamDocumentationForConstructor(className)#> <#+ } } #> <#+ // Generates methods for the client that have request members as parameters for easy calls to the operation // Only generates them if they are specified in the customizations of the service public void AddSimpleClientMethods(Operation operation, bool isSync) { if (this.Config.ServiceModel.Customizations.SimpleMethodsModel.CreateSimpleMethods(operation.Name)) { var forms = this.Config.ServiceModel.Customizations.SimpleMethodsModel.SimpleMethods[operation.Name].Forms; var members = this.Config.ServiceModel.FindShape(operation.RequestStructure.Name).Members; foreach (var form in forms) { string currentParams = this.Config.ServiceModel.Customizations.SimpleMethodsModel.GetSimpleParameters(form, members); var docMembers = this.Config.ServiceModel.Customizations.SimpleMethodsModel.GetFormMembers(form, members); this.FormatOperationDocumentation(operation, docMembers, isSync); if (isSync) { if(operation.IsDeprecated) { #> [Obsolete("<#=operation.DeprecationMessage#>")] <#+ } #> public virtual <#=operation.Name#>Response <#=operation.Name#>(<#=currentParams#>) <#+ } else { if (!string.IsNullOrEmpty(currentParams)) currentParams += ", "; if(operation.IsDeprecated) { #> [Obsolete("<#=operation.DeprecationMessage#>")] <#+ } #> public virtual Task<<#=operation.Name#>Response> <#=operation.Name#>Async(<#=currentParams#>System.Threading.CancellationToken cancellationToken = default(CancellationToken)) <#+ } #> { var request = new <#=operation.Name#>Request(); <#+ foreach (var member in docMembers) { #> request.<#=member.PropertyName#> = <#=GeneratorHelpers.CamelCaseParam(member.PropertyName)#>; <#+ } if (isSync) { #> return <#=operation.Name#>(request); <#+ } else { #> return <#=operation.Name#>Async(request, cancellationToken); <#+ } #> } <#+ } } } #> <#+ // Generates methods for the interface that have request members as parameters for easy calls to the operation // Only generates them if they are specified in the customizations of the service public void AddSimpleClientMethodInterfaces(Operation operation, bool isSync) { if (this.Config.ServiceModel.Customizations.SimpleMethodsModel.CreateSimpleMethods(operation.Name)) { var forms = this.Config.ServiceModel.Customizations.SimpleMethodsModel.SimpleMethods[operation.Name].Forms; var members = this.Config.ServiceModel.FindShape(operation.RequestStructure.Name).Members; foreach (var form in forms) { string currentParams = this.Config.ServiceModel.Customizations.SimpleMethodsModel.GetSimpleParameters(form, members); var docMembers = this.Config.ServiceModel.Customizations.SimpleMethodsModel.GetFormMembers(form, members); this.FormatOperationDocumentation(operation, docMembers, isSync); if (isSync) { if(operation.IsDeprecated) { #> [Obsolete("<#=operation.DeprecationMessage#>")] <#+ } #> <#=operation.Name#>Response <#=operation.Name#>(<#=currentParams#>); <#+ } else { if (!string.IsNullOrEmpty(currentParams)) currentParams += ", "; if(operation.IsDeprecated) { #> [Obsolete("<#=operation.DeprecationMessage#>")] <#+ } #> Task<<#=operation.Name#>Response> <#=operation.Name#>Async(<#=currentParams#>System.Threading.CancellationToken cancellationToken = default(CancellationToken)); <#+ } } } } #> <#+ // Generates constructors for operation requests that have request members in the parameters for easy creation of requests // Only generates them if they are specified in the customizations of the service public void AddSimpleRequestConstructors(string className, Shape structure, string nameSpace) { if (this.Config.ServiceModel.Customizations.SimpleConstructorsModel.CreateSimpleConstructors(className)) { var forms = this.Config.ServiceModel.Customizations.SimpleConstructorsModel.SimpleConstructors[className].Forms; var members = structure.Members; #> /// /// Empty constructor used to set properties independently even when a simple constructor is available /// public <#=className#>() { } <#+ foreach (var form in forms) { string currentParams = this.Config.ServiceModel.Customizations.SimpleConstructorsModel.GetSimpleParameters(form, members); var docMembers = this.Config.ServiceModel.Customizations.SimpleConstructorsModel.GetFormMembers(form, members); #> <#+ FormatSimpleConstructorDocumentation(className, docMembers); #> public <#=className#>(<#=currentParams#>) { <#+ foreach (var member in docMembers) { #> <#=member.VariableName#> = <#=GeneratorHelpers.CamelCaseParam(member.PropertyName)#>; <#+ } #> } <#+ } } } #>