From d97b1da90c75caf0c4814a8393340754c394495d Mon Sep 17 00:00:00 2001 From: Jim Schubert Date: Sun, 15 Jan 2017 11:19:10 -0600 Subject: [PATCH] [csharp] Support internal access of generated code (#4560) Allows users to specify 'nonPublicApi' additional property (and C# client CLI switch) to reduce visibility of classes created by the generator. This includes API and Models as well as supporting code like ApiClient and other infrastructure. The requirement is to support codegen generated code to be embedded within other applications where the generated code is not intended to be publicly consumable or publicy exposed. An example would be an SDK which internally consumes an API via the generated code; we wouldn't want the internal API implementation exposed as part of that SDK. Reducing visibility of the classes effectively makes the entire implementation internal, regardless of the public modifier on methods or static members. To fully make all members internal it would require explicit interface implementation, which is not ideal. see #4401 --- .../io/swagger/codegen/CodegenConstants.java | 3 +++ .../languages/CSharpClientCodegen.java | 23 +++++++++++++++++++ .../main/resources/csharp/ApiClient.mustache | 2 +- .../resources/csharp/ApiException.mustache | 2 +- .../resources/csharp/ApiResponse.mustache | 2 +- .../resources/csharp/Configuration.mustache | 2 +- .../csharp/ExceptionFactory.mustache | 4 ++-- .../resources/csharp/IApiAccessor.mustache | 2 +- .../src/main/resources/csharp/api.mustache | 4 ++-- .../main/resources/csharp/enumClass.mustache | 2 +- .../main/resources/csharp/modelEnum.mustache | 2 +- .../resources/csharp/modelGeneric.mustache | 2 +- .../resources/csharp/modelInnerEnum.mustache | 2 +- .../main/resources/csharp/visibility.mustache | 1 + .../csharp/CSharpClientOptionsTest.java | 2 ++ .../options/CSharpClientOptionsProvider.java | 1 + 16 files changed, 43 insertions(+), 13 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/csharp/visibility.mustache diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java index f5c759d4d04..aacb5f2737e 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java @@ -144,4 +144,7 @@ public class CodegenConstants { public static final String GENERATE_PROPERTY_CHANGED = "generatePropertyChanged"; public static final String GENERATE_PROPERTY_CHANGED_DESC = "Specifies that models support raising property changed events."; + + public static final String NON_PUBLIC_API = "nonPublicApi"; + public static final String NON_PUBLIC_API_DESC = "Generates code with reduced access modifiers; allows embedding elsewhere without exposing non-public API calls to consumers."; } diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java index cf4bc656d83..526fffeda18 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java @@ -45,6 +45,9 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen { protected Map regexModifiers; protected final Map frameworks; + // By default, generated code is considered public + protected boolean nonPublicApi = Boolean.FALSE; + public CSharpClientCodegen() { super(); modelTemplateFiles.put("model.mustache", ".cs"); @@ -130,6 +133,14 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen { CodegenConstants.PACKAGE_DESCRIPTION_DESC, this.generatePropertyChanged); + // NOTE: This will reduce visibility of all public members in templates. Users can use InternalsVisibleTo + // https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute(v=vs.110).aspx + // to expose to shared code if the generated code is not embedded into another project. Otherwise, users of codegen + // should rely on default public visibility. + addSwitch(CodegenConstants.NON_PUBLIC_API, + CodegenConstants.NON_PUBLIC_API_DESC, + this.nonPublicApi); + regexModifiers = new HashMap(); regexModifiers.put('i', "IgnoreCase"); regexModifiers.put('m', "Multiline"); @@ -232,6 +243,10 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen { .get(CodegenConstants.OPTIONAL_ASSEMBLY_INFO).toString())); } + if (additionalProperties.containsKey(CodegenConstants.NON_PUBLIC_API)) { + setNonPublicApi(Boolean.valueOf(additionalProperties.get(CodegenConstants.NON_PUBLIC_API).toString())); + } + final String testPackageName = testPackageName(); String packageFolder = sourceFolder + File.separator + packageName; String clientPackageDir = packageFolder + File.separator + clientPackage; @@ -555,6 +570,14 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen { this.generatePropertyChanged = generatePropertyChanged; } + public boolean isNonPublicApi() { + return nonPublicApi; + } + + public void setNonPublicApi(final boolean nonPublicApi) { + this.nonPublicApi = nonPublicApi; + } + @Override public String toModelDocFilename(String name) { return toModelFilename(name); diff --git a/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache index 33b631280c2..8960ccfe59e 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache @@ -19,7 +19,7 @@ namespace {{packageName}}.Client /// /// API client is mainly responsible for making the HTTP call to the API backend. /// - public partial class ApiClient + {{>visibility}} partial class ApiClient { private JsonSerializerSettings serializerSettings = new JsonSerializerSettings { diff --git a/modules/swagger-codegen/src/main/resources/csharp/ApiException.mustache b/modules/swagger-codegen/src/main/resources/csharp/ApiException.mustache index ad7c2264d78..ca8044580f2 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/ApiException.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/ApiException.mustache @@ -6,7 +6,7 @@ namespace {{packageName}}.Client /// /// API Exception /// - public class ApiException : Exception + {{>visibility}} class ApiException : Exception { /// /// Gets or sets the error code (HTTP status code) diff --git a/modules/swagger-codegen/src/main/resources/csharp/ApiResponse.mustache b/modules/swagger-codegen/src/main/resources/csharp/ApiResponse.mustache index d8c1b79e545..d04575d7ad9 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/ApiResponse.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/ApiResponse.mustache @@ -7,7 +7,7 @@ namespace {{packageName}}.Client /// /// API Response /// - public class ApiResponse + {{>visibility}} class ApiResponse { /// /// Gets or sets the status code (HTTP status code) diff --git a/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache b/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache index 108b85e48f8..0e1856725df 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache @@ -11,7 +11,7 @@ namespace {{packageName}}.Client /// /// Represents a set of configuration settings /// - public class Configuration + {{>visibility}} class Configuration { /// /// Initializes a new instance of the Configuration class with different settings diff --git a/modules/swagger-codegen/src/main/resources/csharp/ExceptionFactory.mustache b/modules/swagger-codegen/src/main/resources/csharp/ExceptionFactory.mustache index c25b88ee614..f0ebb0b31ce 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/ExceptionFactory.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/ExceptionFactory.mustache @@ -10,6 +10,6 @@ namespace {{packageName}}.Client /// /// Method name /// Response - /// Exceptions - public delegate Exception ExceptionFactory(string methodName, IRestResponse response); + /// Exceptions + {{>visibility}} delegate Exception ExceptionFactory(string methodName, IRestResponse response); } diff --git a/modules/swagger-codegen/src/main/resources/csharp/IApiAccessor.mustache b/modules/swagger-codegen/src/main/resources/csharp/IApiAccessor.mustache index df236b8f8c8..290c9b6ffdc 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/IApiAccessor.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/IApiAccessor.mustache @@ -11,7 +11,7 @@ namespace {{packageName}}.Client /// /// Represents configuration aspects required to interact with the API endpoints. /// - public interface IApiAccessor + {{>visibility}} interface IApiAccessor { /// /// Gets or sets the configuration object diff --git a/modules/swagger-codegen/src/main/resources/csharp/api.mustache b/modules/swagger-codegen/src/main/resources/csharp/api.mustache index 18c949980cb..c3d73306149 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/api.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/api.mustache @@ -14,7 +14,7 @@ namespace {{packageName}}.{{apiPackage}} /// /// Represents a collection of functions to interact with the API endpoints /// - public interface {{interfacePrefix}}{{classname}} : IApiAccessor + {{>visibility}} interface {{interfacePrefix}}{{classname}} : IApiAccessor { #region Synchronous Operations {{#operation}} @@ -73,7 +73,7 @@ namespace {{packageName}}.{{apiPackage}} /// /// Represents a collection of functions to interact with the API endpoints /// - public partial class {{classname}} : {{interfacePrefix}}{{classname}} + {{>visibility}} partial class {{classname}} : {{interfacePrefix}}{{classname}} { private {{packageName}}.Client.ExceptionFactory _exceptionFactory = (name, response) => null; diff --git a/modules/swagger-codegen/src/main/resources/csharp/enumClass.mustache b/modules/swagger-codegen/src/main/resources/csharp/enumClass.mustache index 5249d754577..b11d14cdfc0 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/enumClass.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/enumClass.mustache @@ -3,7 +3,7 @@ /// {{#description}} /// {{{description}}}{{/description}} [JsonConverter(typeof(StringEnumConverter))] - public enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} + {{>visibility}} enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { {{#allowableValues}}{{#enumVars}} /// diff --git a/modules/swagger-codegen/src/main/resources/csharp/modelEnum.mustache b/modules/swagger-codegen/src/main/resources/csharp/modelEnum.mustache index ff007904f46..b0dfa881eb2 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/modelEnum.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/modelEnum.mustache @@ -3,7 +3,7 @@ /// {{#description}} /// {{{description}}}{{/description}} [JsonConverter(typeof(StringEnumConverter))] - public enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} + {{>visibility}} enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { {{#allowableValues}}{{#enumVars}} /// diff --git a/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache b/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache index 5e1d0721dc2..09c232acefd 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache @@ -5,7 +5,7 @@ {{#generatePropertyChanged}} [ImplementPropertyChanged] {{/generatePropertyChanged}} - public partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}>, IValidatableObject + {{>visibility}} partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}>, IValidatableObject { {{#vars}} {{#isEnum}} diff --git a/modules/swagger-codegen/src/main/resources/csharp/modelInnerEnum.mustache b/modules/swagger-codegen/src/main/resources/csharp/modelInnerEnum.mustache index 855a710c7ed..d851a2dddc6 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/modelInnerEnum.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/modelInnerEnum.mustache @@ -4,7 +4,7 @@ /// {{#description}} /// {{{description}}}{{/description}} [JsonConverter(typeof(StringEnumConverter))] - public enum {{#datatypeWithEnum}}{{&.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} + {{>visibility}} enum {{#datatypeWithEnum}}{{&.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} { {{#allowableValues}}{{#enumVars}} /// diff --git a/modules/swagger-codegen/src/main/resources/csharp/visibility.mustache b/modules/swagger-codegen/src/main/resources/csharp/visibility.mustache new file mode 100644 index 00000000000..a1d1f4163d4 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/csharp/visibility.mustache @@ -0,0 +1 @@ +{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CSharpClientOptionsTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CSharpClientOptionsTest.java index 8bc55f211be..195d928d8c6 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CSharpClientOptionsTest.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CSharpClientOptionsTest.java @@ -50,6 +50,8 @@ public class CSharpClientOptionsTest extends AbstractOptionsTest { times = 1; clientCodegen.setGeneratePropertyChanged(true); times = 1; + clientCodegen.setNonPublicApi(true); + times = 1; clientCodegen.setInterfacePrefix("X"); times = 1; }}; diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/CSharpClientOptionsProvider.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/CSharpClientOptionsProvider.java index 9bbc6512911..833184775ba 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/CSharpClientOptionsProvider.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/CSharpClientOptionsProvider.java @@ -35,6 +35,7 @@ public class CSharpClientOptionsProvider implements OptionsProvider { .put(CodegenConstants.OPTIONAL_EMIT_DEFAULT_VALUES, "true") .put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, "true") .put(CodegenConstants.GENERATE_PROPERTY_CHANGED, "true") + .put(CodegenConstants.NON_PUBLIC_API, "true") .put(CodegenConstants.INTERFACE_PREFIX, "X") .build(); }