private (bool success, string failureReason, TypeBase name) ParseNameSchema(ResourceDefinition resource, ProviderDefinition providerDefinition) { var finalProvidersMatch = CodeModelProcessor.parentScopePrefix.Match(resource.DeclaringMethod.Url); var routingScope = resource.DeclaringMethod.Url.Substring(finalProvidersMatch.Length); // get the resource name parameter, e.g. {fooName} var resNameParam = routingScope.Substring(routingScope.LastIndexOf('/') + 1); if (CodeModelProcessor.IsPathVariable(resNameParam)) { // strip the enclosing braces resNameParam = CodeModelProcessor.TrimParamBraces(resNameParam); // look up the type var param = resource.DeclaringMethod.Parameters.FirstOrDefault(p => p.SerializedName == resNameParam); if (param == null) { return(false, $"Unable to locate parameter with name '{resNameParam}'", null); } var nameType = ParseType(param.ModelType, param.ModelType); return(true, string.Empty, nameType); } if (!resNameParam.All(c => char.IsLetterOrDigit(c))) { return(false, $"Unable to process non-alphanumeric name '{resNameParam}'", null); } // Resource name is a constant return(true, string.Empty, CreateConstantResourceName(resource.Descriptor, resNameParam)); }
public override async Task Generate(CodeModel serviceClient) { var apiVersions = serviceClient.Methods .SelectMany(method => method.XMsMetadata.apiVersions) .Concat(new [] { serviceClient.ApiVersion }) .Where(each => each != null) .Distinct().ToArray(); foreach (var version in apiVersions) { var results = CodeModelProcessor.GenerateTypes(serviceClient, version); foreach (var result in results) { var generatedTypes = result.TypeFactory.GetTypes(); var typesJson = TypeSerializer.Serialize(generatedTypes); await Write(typesJson, Path.Combine(result.ProviderNamespace, result.ApiVersion, "types.json"), true); } } }
private GenerateResult Process() { foreach (var resource in definition.ResourceDefinitions) { var descriptor = resource.Descriptor; var putBody = resource.DeclaringMethod.Body?.ModelType as CompositeType; var getBody = (resource.GetMethod?.Responses.GetValueOrDefault(HttpStatusCode.OK)?.Body as CompositeType) ?? (resource.GetMethod?.DefaultResponse?.Body as CompositeType) ?? putBody; var(success, failureReason, resourceName) = ParseNameSchema(resource, definition); if (!success) { CodeModelProcessor.LogWarning($"Skipping resource type {descriptor.FullyQualifiedType} under path '{resource.DeclaringMethod.Url}': {failureReason}"); continue; } if (putBody == null) { CodeModelProcessor.LogWarning($"Skipping resource type {descriptor.FullyQualifiedType} under path '{resource.DeclaringMethod.Url}': No resource body defined"); continue; } var resourceProperties = GetStandardizedResourceProperties(resource.Descriptor, resourceName); var resourceDefinition = CreateObject(descriptor.FullyQualifiedType, putBody, resourceProperties); resource.Type = factory.Create(() => new ResourceType { Name = $"{descriptor.FullyQualifiedType}@{descriptor.ApiVersion}", Body = factory.GetReference(resourceDefinition), }); var putProperties = putBody.ComposedProperties .Where(p => p.SerializedName != null) .Where(p => !resourceProperties.ContainsKey(p.SerializedName)) .ToDictionary(p => p.SerializedName, StringComparer.OrdinalIgnoreCase); var getProperties = getBody.ComposedProperties .Where(p => p.SerializedName != null) .Where(p => !resourceProperties.ContainsKey(p.SerializedName)) .ToDictionary(p => p.SerializedName, StringComparer.OrdinalIgnoreCase); foreach (var property in putProperties.Keys.Concat(getProperties.Keys.Where(x => !putProperties.ContainsKey(x)))) { var isWritable = putProperties.TryGetValue(property, out var putProperty); var isReadable = getProperties.TryGetValue(property, out var getProperty); var propertyDefinition = ParseType(putProperty?.ModelType, getProperty?.ModelType); if (propertyDefinition != null) { var flags = ParsePropertyFlags(putProperty, getProperty); resourceProperties[property] = CreateObjectProperty(propertyDefinition, flags); } } if (resourceDefinition is DiscriminatedObjectType discriminatedObjectType) { HandlePolymorphicType(discriminatedObjectType, putBody, getBody); } } return(new GenerateResult( definition.Namespace, definition.ApiVersion, factory, definition.ResourceDefinitions.Select(x => x.Descriptor))); }