Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement discriminator support in v3 generator #113

Merged
merged 10 commits into from
Apr 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions src/CodeGeneratorGo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ public class CodeGeneratorGo : CodeGenerator
private const string ModelsFileName = "models";
private const string ClientFileName = "client";
private const string VersionFileName = "version";
private const string MarshallingFileName = "marshalling";
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MarshallingFileName [](start = 29, length = 19)

note that I removed the marshalling file from the output. it seems most of it should go to the models file

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason for this file was to separate the exported types from the non-exported types/implementation details (i.e. the content of marshalling.go is interesting to us but not to consumers of the SDK). If merging this into the models file makes it easier to generate the content then we can leave it merged.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense, but I think to keep the generator code cleaner its easier to put them in the models also would prefer to have all the publicly used types ( and their marshallers ) to be in the models.

private const string ResponderFileName = "responder_policy";
private const string ResponseErrorFileName = "response_error";
private const string ValidationFileName = "validation";
Expand All @@ -33,7 +32,6 @@ public CodeGeneratorGo()
ModelsFileName,
ClientFileName,
VersionFileName,
MarshallingFileName,
ResponderFileName,
ResponseErrorFileName,
ValidationFileName
Expand Down Expand Up @@ -101,12 +99,6 @@ public override async Task Generate(CodeModel cm)
{
await Write(template.Item1, FormatFileName(template.Item2));
}

if (codeModel.RequiresMarshallers.Any())
{
var marshallingTemplate = new Marshalling { Model = codeModel };
await Write(marshallingTemplate, FormatFileName(MarshallingFileName));
}
}

/// <summary>
Expand Down
280 changes: 122 additions & 158 deletions src/CodeNamerGo.cs

Large diffs are not rendered by default.

63 changes: 40 additions & 23 deletions src/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public static CodeModelGo Cast(this CodeModel cm)
}

/// <summary>
/// This method changes string to sentence where is make the first word
/// This method changes string to sentence where is make the first word
/// of sentence to lowercase (unless it is an acronym). The sentence is coming directly from swagger.
/// </summary>
/// <param name="value"></param>
Expand All @@ -54,15 +54,13 @@ public static string ToSentence(this string value)
{
return string.Empty;
}
else

value = value.Trim();
if (value.StartsWithAcronym())
{
value = value.Trim();
if (value.StartsWithAcronym())
{
return value;
}
return value.First().ToString().ToLowerInvariant() + (value.Length > 1 ? value.Substring(1) : "");
return value;
}
return value.First().ToString().ToLowerInvariant() + (value.Length > 1 ? value.Substring(1) : "");
}

/// <summary>
Expand All @@ -74,7 +72,7 @@ public static string ToSentence(this string value)
public static bool StartsWithAcronym(this string value)
{
string firstWord = value.Trim().Split(' ', '-', '_').First();
return firstWord.Length > 1 && firstWord.All(c => char.IsUpper(c));
return firstWord.Length > 1 && firstWord.All(char.IsUpper);
}

/// <summary>
Expand Down Expand Up @@ -126,7 +124,7 @@ public static string ToShortName(this string longName)
}

/// <summary>
/// This method checks if MethodGroupName is plural of package name.
/// This method checks if MethodGroupName is plural of package name.
/// It returns false for packages not listed in dictionary 'plural'.
/// Example, group EventHubs in package EventHub.
/// Refactor -> Namer, but also could be used by the CodeModelTransformer
Expand Down Expand Up @@ -296,24 +294,43 @@ public static bool CanBeNull(this IModelType type)
/// <param name="imports"></param>
public static void AddImports(this IModelType type, HashSet<string> imports)
{
if (type is DictionaryTypeGo)
switch (type)
{
(type as DictionaryTypeGo).AddImports(imports);
}
else if (type is PrimaryTypeGo)
{
(type as PrimaryTypeGo).AddImports(imports);
}
else if (type is SequenceTypeGo)
{
(type as SequenceTypeGo).AddImports(imports);
case DictionaryTypeGo dictionaryType:
dictionaryType.AddImports(imports);
break;
case PrimaryTypeGo primaryType:
primaryType.AddImports(imports);
break;
default:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default [](start = 16, length = 7)

Could a different go type arrive here? Something different to a sequence?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have it the same in the v2 generator. looking at it, Composite Type also has AddImports but that will be just the imports of its fields

(type as SequenceTypeGo)?.AddImports(imports);
break;
}
}

public static bool ShouldBeSyntheticType(this IModelType type)
{
return (type is PrimaryType || type is SequenceType || type is DictionaryType || type is EnumType ||
(type is CompositeTypeGo && (type as CompositeTypeGo).IsPolymorphicResponse()));
{
return (type is PrimaryType || type is SequenceType || type is DictionaryType || type is EnumType ||
(type is CompositeTypeGo && ((CompositeTypeGo) type).IsPolymorphicResponse()));
}

/// <summary>
/// Gets if the type has an interface.
/// </summary>
public static bool HasInterface(this IModelType type)
{
return (type is CompositeTypeGo compositeType) &&
(compositeType.IsRootType || compositeType.BaseIsPolymorphic && !compositeType.IsLeafType);
}

/// <summary>
/// Gets the interface name for the type.
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static string GetInterfaceName(this IModelType type)
{
return $"Basic{type.Name}";
}

/// <summary>
Expand Down
83 changes: 21 additions & 62 deletions src/Model/CodeModelGo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,7 @@ public class CodeModelGo : CodeModel

public string Version { get; }

public string UserAgent
{
get
{
return $"Azure-SDK-For-Go/{Version} arm-{Namespace}/{ApiVersion}";
}
}
public string UserAgent => $"Azure-SDK-For-Go/{Version} {Namespace}/{ApiVersion}";

public CodeModelGo()
{
Expand All @@ -37,41 +31,27 @@ public CodeModelGo()

public override string Namespace
{
get
{
if (string.IsNullOrEmpty(base.Namespace))
{
return base.Namespace;
}

return base.Namespace.ToLowerInvariant();
}
set
{
base.Namespace = value;
}
get => string.IsNullOrEmpty(base.Namespace) ? base.Namespace : base.Namespace.ToLowerInvariant();
set => base.Namespace = value;
}

public string ServiceName => CodeNamer.Instance.PascalCase(Namespace ?? string.Empty);

public string GetDocumentation()
{
return $"Package {Namespace} implements the Azure ARM {ServiceName} service API version {ApiVersion}.\n\n{(Documentation ?? string.Empty).UnwrapAnchorTags()}";
}
public string GetDocumentation() => $"Package {Namespace} implements the Azure ARM {ServiceName} service API version {ApiVersion}.\n\n{(Documentation ?? string.Empty).UnwrapAnchorTags()}";

public string BaseClient => CodeNamerGo.Instance.ExportClientTypes ? "ManagementClient" : "managementClient";

public bool IsCustomBaseUri => Extensions.ContainsKey(SwaggerExtensions.ParameterizedHostExtension);

public string APIType => (string)Settings.Instance.Host?.GetValue<string>("openapi-type").Result;
public string APIType => Settings.Instance.Host?.GetValue<string>("openapi-type").Result;

public IEnumerable<string> ClientImports
{
get
{
var imports = new HashSet<string>();
imports.UnionWith(CodeNamerGo.Instance.PipelineImports);
var clientMg = MethodGroups.Where(mg => string.IsNullOrEmpty(mg.Name)).FirstOrDefault();
var clientMg = MethodGroups.FirstOrDefault(mg => string.IsNullOrEmpty(mg.Name));
if (clientMg != null)
{
imports.UnionWith(clientMg.Imports);
Expand All @@ -96,10 +76,12 @@ public IEnumerable<string> ModelImports
var addStrConvImport = false;
var addBase64Import = false;
// Create an ordered union of the imports each model requires
var imports = new HashSet<string>();
imports.Add(PrimaryTypeGo.GetImportLine(package: "net/http"));
imports.Add(PrimaryTypeGo.GetImportLine(package: "reflect"));
imports.Add(PrimaryTypeGo.GetImportLine(package: "strings"));
var imports = new HashSet<string>
{
PrimaryTypeGo.GetImportLine(package: "net/http"),
PrimaryTypeGo.GetImportLine(package: "reflect"),
PrimaryTypeGo.GetImportLine(package: "strings")
};

ModelTypes.Cast<CompositeTypeGo>()
.ForEach(mt =>
Expand Down Expand Up @@ -159,7 +141,7 @@ public string GlobalParameters
{
declarations.Add(
string.Format(
(p.IsRequired || p.ModelType.CanBeNull() ? "{0} {1}" : "{0} *{1}"),
((PropertyGo)p).IsPointer ? "{0} *{1}" : "{0} {1}",
p.Name.Value.ToSentence(), p.ModelType.Name));
}
}
Expand Down Expand Up @@ -194,7 +176,7 @@ public string GlobalDefaultParameters
{
declarations.Add(
string.Format(
(p.IsRequired || p.ModelType.CanBeNull() ? "{0} {1}" : "{0} *{1}"),
(((PropertyGo)p).IsPointer ? "{0} *{1}" : "{0} {1}"),
p.Name.Value.ToSentence(), p.ModelType.Name.Value.ToSentence()));
}
}
Expand Down Expand Up @@ -269,14 +251,9 @@ public string HelperAllGlobalParameters
}
}

public IEnumerable<MethodGo> ClientMethods
{
get
{
public IEnumerable<MethodGo> ClientMethods =>
// client methods are the ones with no method group
return Methods.Cast<MethodGo>().Where(m => string.IsNullOrEmpty(m.MethodGroup.Name));
}
}
Methods.Cast<MethodGo>().Where(m => string.IsNullOrEmpty(m.MethodGroup.Name));

/// FormatVersion normalizes a version string into a SemVer if it resembles one. Otherwise,
/// it returns the original string unmodified. If version is empty or only comprised of
Expand Down Expand Up @@ -313,36 +290,18 @@ public static string FormatVersion(string version)
/// <summary>
/// Returns true if any model types contain a metadata property.
/// </summary>
public bool UsesMetadataType
{
get
{
return ModelTypes.Where(m => m.Properties.Cast<PropertyGo>().Where(p => p.IsMetadata).Any()).Any();
}
}
public bool UsesMetadataType => ModelTypes.Any(m => m.Properties.Cast<PropertyGo>().Any(p => p.IsMetadata));

/// <summary>
/// Returns true if any model types contain an Etag property.
/// </summary>
public bool UsesETags
{
get
{
return ModelTypes.Where(m => m.Properties.Where(p => p.ModelType.IsETagType()).Any()).Any();
}
}
public bool UsesETags => ModelTypes.Any(m => m.Properties.Any(p => p.ModelType.IsETagType()));

/// <summary>
/// Returns a collection of composite types that require custom marshalling and/or
/// unmarshalling. Can be empty if there are no types requriring marshallers.
/// Returns a collection of composite types that require datetime handleing in a custom marshaller and/or
/// unmarshaller. Can be empty if there are no types requriring marshallers.
/// </summary>
public IEnumerable<CompositeTypeGo> RequiresMarshallers
{
get
{
return ModelTypes.Cast<CompositeTypeGo>().Where(m => m.Properties.Where(p => p.ModelType.IsDateTimeType()).Any());
}
}
public IEnumerable<CompositeTypeGo> RequiresDateTimeCustomHandling=> ModelTypes.Cast<CompositeTypeGo>().Where(m => m.IsDateTimeCustomHandlingRequired);

/// <summary>
/// Returns the encoding type used for serialization (e.g. xml or json).
Expand Down
Loading