private static MethodDeclarationSyntax GenerateMethod(SourceFileContext ctx, ServiceDetails service)
        {
            var name = $"Add{service.ClientAbstractTyp.Name}";
            var serviceCollection = ctx.Type <IServiceCollection>();
            var services          = Parameter(serviceCollection, "services")
                                    .WithModifiers(SyntaxTokenList.Create(Token(SyntaxKind.ThisKeyword).WithTrailingSpace()));
            var actionType = ctx.Type(Typ.Generic(typeof(Action <>), service.BuilderTyp));
            var action     = Parameter(actionType, "action", @default: Null);

            var builderType = ctx.Type(service.BuilderTyp);
            var builder     = Local(builderType, "builder");

            var provider = Parameter(ctx.Type <IServiceProvider>(), "provider");
            var lambda   = Lambda(provider)(
                builder.WithInitializer(New(builderType)()),
                action.Call("Invoke", true)(builder),
                Return(builder.Call("Build")(provider))
                );

            return(Method(Public | Static, serviceCollection, name)(services, action)
                   .WithBody(services.Call("AddSingleton")(lambda))
                   .WithXmlDoc(
                       XmlDoc.Summary("Adds a singleton ", ctx.Type(service.ClientAbstractTyp), " to ", services, "."),
                       XmlDoc.Param(services, "The service collection to add the client to. The services are used to configure the client when requested."),
                       XmlDoc.Param(action, "An optional action to invoke on the client builder. This is invoked before services from ", services, " are used.")
                       ));
        }
Example #2
0
        public ClassDeclarationSyntax GenerateBaseRequestClass(SourceFileContext ctx)
        {
            var cls = Class(
                Modifier.Public | Modifier.Abstract,
                BaseRequestTyp,
                ctx.Type(Typ.Generic(typeof(ClientServiceRequest <>), Typ.GenericParam("TResponse"))))
                      .WithXmlDoc(XmlDoc.Summary($"A base abstract class for {ClassName} requests."));

            using (ctx.InClass(BaseRequestTyp))
            {
                var serviceParam = Parameter(ctx.Type <IClientService>(), "service");
                var ctor         = Ctor(Modifier.Protected, cls, BaseInitializer(serviceParam))(serviceParam)
                                   .WithBody()
                                   .WithXmlDoc(XmlDoc.Summary($"Constructs a new {ClassName}BaseServiceRequest instance."));

                var parameters = CreateParameterList(BaseRequestTyp);

                cls = cls.AddMembers(ctor);
                cls = cls.AddMembers(parameters.SelectMany(p => p.GenerateDeclarations(ctx)).ToArray());

                var initParameters = Method(Modifier.Protected | Modifier.Override, VoidType, "InitParameters")()
                                     .WithBlockBody(
                    BaseExpression().Call("InitParameters")(),
                    parameters.Select(p => p.GenerateInitializer(ctx)).ToArray())
                                     .WithXmlDoc(XmlDoc.Summary($"Initializes {ClassName} parameter list."));

                cls = cls.AddMembers(initParameters);
            }
            return(cls);
        }
Example #3
0
        public static MethodDeclarationSyntax ModifyRequestPartialMethod(SourceFileContext ctx, MethodDetails method)
        {
            var requestParam  = Parameter(ctx.Type(method.RequestTyp), "request").Ref();
            var settingsParam = Parameter(ctx.Type <CallSettings>(), "settings").Ref();

            return(PartialMethod(method.ModifyRequestMethodName)(requestParam, settingsParam));
        }
Example #4
0
        private MethodDeclarationSyntax GenerateMethodDeclaration(SourceFileContext ctx)
        {
            var parameters            = CreateParameterList(RequestTyp);
            var docs                  = new List <DocumentationCommentTriviaSyntax>();
            var methodParameters      = parameters.TakeWhile(p => p.IsRequired).ToList();
            var parameterDeclarations = methodParameters.Select(p => Parameter(ctx.Type(p.Typ), p.CodeParameterName)).ToList();

            if (_restMethod.Description is object)
            {
                docs.Add(XmlDoc.Summary(_restMethod.Description));
            }
            docs.AddRange(methodParameters.Zip(parameterDeclarations).Select(pair => XmlDoc.Param(pair.Second, pair.First.Description)));
            if (BodyTyp is object)
            {
                parameterDeclarations.Insert(0, Parameter(ctx.Type(BodyTyp), "body"));
                docs.Insert(1, XmlDoc.Param(parameterDeclarations[0], "The body of the request."));
            }

            var ctorArguments = new object[] { Field(0, ctx.Type <IClientService>(), "service") }
            .Concat(parameterDeclarations)
            .ToArray();
            var method = Method(Modifier.Public | Modifier.Virtual, ctx.Type(RequestTyp), PascalCasedName)(parameterDeclarations.ToArray())
                         .WithBlockBody(Return(New(ctx.Type(RequestTyp))(ctorArguments)))
                         .WithXmlDoc(docs.ToArray());

            return(method);
        }
Example #5
0
        public IEnumerable <PropertyDeclarationSyntax> GeneratePropertyDeclarations(SourceFileContext ctx)
        {
            var propertyTyp = SchemaTypes.GetTypFromSchema(Parent.Package, _schema, Name, ctx.CurrentTyp, inParameter: false);

            if (propertyTyp.FullName == "System.Nullable<System.DateTime>")
            {
                // DateTime values generate two properties: one raw as a string, and one DateTime version.
                var rawProperty = AutoProperty(Modifier.Public | Modifier.Virtual, ctx.Type <string>(), PropertyName + "Raw", hasSetter: true)
                                  .WithAttribute(ctx.Type <JsonPropertyAttribute>())(Name);
                if (_schema.Description is object)
                {
                    rawProperty = rawProperty.WithXmlDoc(XmlDoc.Summary(_schema.Description));
                }
                yield return(rawProperty);

                var valueParameter = Parameter(ctx.Type(propertyTyp), "value");
                yield return(Property(Modifier.Public | Modifier.Virtual, ctx.Type(propertyTyp), PropertyName)
                             .WithAttribute(ctx.Type <JsonIgnoreAttribute>())()
                             .WithXmlDoc(XmlDoc.Summary(XmlDoc.SeeAlso(ctx.Type <DateTime>()), " representation of ", rawProperty, "."))
                             .WithGetBody(Return(ctx.Type(typeof(Utilities)).Call(nameof(Utilities.GetDateTimeFromString))(rawProperty)))
                             .WithSetBody(rawProperty.Assign(ctx.Type(typeof(Utilities)).Call(nameof(Utilities.GetStringFromDateTime))(valueParameter))));
            }
            else
            {
                var property = AutoProperty(Modifier.Public | Modifier.Virtual, ctx.Type(propertyTyp), PropertyName, hasSetter: true)
                               .WithAttribute(ctx.Type <JsonPropertyAttribute>())(Name);
                if (_schema.Description is object)
                {
                    property = property.WithXmlDoc(XmlDoc.Summary(_schema.Description));
                }
                yield return(property);
            }
        }
Example #6
0
        private static IEnumerable <MemberDeclarationSyntax> PaginatedPartialClasses(SourceFileContext ctx, ServiceDetails svc, HashSet <Typ> seenPaginatedResponseTyps)
        {
            var paginatedMethods = svc.Methods.OfType <MethodDetails.Paginated>();

            foreach (var representingMethod in paginatedMethods
                     .GroupBy(m => m.RequestTyp)
                     .Select(typMethodGrp => typMethodGrp.First()))
            {
                yield return(PaginatedPartialInterfaceClass(ctx, representingMethod.RequestTyp, representingMethod.RequestMessageDesc));
            }

            foreach (var method in paginatedMethods)
            {
                if (seenPaginatedResponseTyps.Add(method.ResponseTyp))
                {
                    var cls = Class(Public | Partial, method.ResponseTyp, baseTypes: ctx.Type(Typ.Generic(typeof(IPageResponse <>), method.ResourceTyp)));
                    using (ctx.InClass(cls))
                    {
                        var propertyName         = method.ResourcesFieldName;
                        var genericGetEnumerator = Method(Public, ctx.Type(Typ.Generic(typeof(IEnumerator <>), method.ResourceTyp)), "GetEnumerator")()
                                                   .WithBody(Property(Public, ctx.TypeDontCare, propertyName).Call(nameof(IEnumerable <int> .GetEnumerator))())
                                                   .WithXmlDoc(XmlDoc.Summary("Returns an enumerator that iterates through the resources in this response."));
                        var getEnumerator = Method(None, ctx.Type <IEnumerator>(), "GetEnumerator")()
                                            .WithExplicitInterfaceSpecifier(ctx.Type <IEnumerable>())
                                            .WithBody(This.Call(genericGetEnumerator)());
                        cls = cls.AddMembers(genericGetEnumerator, getEnumerator);
                    }
                    yield return(cls);
                }
            }
        }
Example #7
0
        public ClassDeclarationSyntax GenerateBaseRequestClass(SourceFileContext ctx)
        {
            var cls = Class(
                Modifier.Public,
                Typ.Generic(Typ.Manual(PackageName, $"{ClassName}BaseServiceRequest"), Typ.GenericParam("TResponse")),
                ctx.Type(Typ.Generic(typeof(ClientServiceRequest <>), Typ.GenericParam("TResponse"))))
                      .WithXmlDoc(XmlDoc.Summary($"A base abstract class for {ClassName} requests."));

            var serviceParam = Parameter(ctx.Type <IClientService>(), "service");
            var ctor         = Ctor(Modifier.Protected, cls, BaseInitializer(serviceParam))(serviceParam)
                               .WithBody()
                               .WithXmlDoc(XmlDoc.Summary($"Constructs a new {ClassName}BaseServiceRequest instance."));

            cls = cls.AddMembers(ctor);

            var parameters = _discoveryDoc.Parameters.Select(p => new ParameterModel(p.Key, p.Value))
                             .OrderBy(p => p.PropertyName)
                             .ToList();

            cls = cls.AddMembers(parameters.Select(p => p.GenerateProperty(ctx)).ToArray());

            var initParameters = Method(Modifier.Protected | Modifier.Override, VoidType, "InitParameters")()
                                 .WithBlockBody(
                BaseExpression().Call("InitParameters")(),
                parameters.Select(p => p.GenerateInitializer(ctx)).ToArray())
                                 .WithXmlDoc(XmlDoc.Summary($"Initializes {ClassName} parameter list."));

            cls = cls.AddMembers(initParameters);
            return(cls);
        }
Example #8
0
        public PropertyDeclarationSyntax GenerateProperty(SourceFileContext ctx)
        {
            var property = AutoProperty(Modifier.Public | Modifier.Virtual, ctx.Type <string>(), PropertyName)
                           // TODO: Attribute arguments
                           // TODO: Default, Minimum, Maximum? Commented out...
                           .WithAttribute(ctx.Type <RequestParameterAttribute>());

            if (_schema.Description is string description)
            {
                property = property.WithXmlDoc(XmlDoc.Summary(description));
            }
            return(property);
        }
        private PropertyDeclarationSyntax GenerateProperty(SourceFileContext ctx)
        {
            var propertyType       = ctx.Type(Typ);
            var locationExpression = ctx.Type <RequestParameterType>().Access(Location.ToString());
            var property           = AutoProperty(Modifier.Public | Modifier.Virtual, propertyType, PropertyName, hasSetter: true, setterIsPrivate: IsRequired)
                                     .WithAttribute(ctx.Type <RequestParameterAttribute>())(Name, locationExpression);

            if (_schema.Description is string description)
            {
                property = property.WithXmlDoc(XmlDoc.Summary(description));
            }
            return(property);
        }
        private PropertyDeclarationSyntax GenerateRepeatedOptionalEnumProperty(SourceFileContext ctx)
        {
            var propertyType       = ctx.Type(Typ.Generic(Typ.Of(typeof(Repeatable <>)), Typ.GenericArgTyps.Single()));
            var locationExpression = ctx.Type <RequestParameterType>().Access(Location.ToString());
            var property           = AutoProperty(Modifier.Public | Modifier.Virtual, propertyType, PropertyName + "List", hasSetter: true)
                                     .WithAttribute(ctx.Type <RequestParameterAttribute>())(Name, locationExpression);

            if (_schema.Description is string description)
            {
                property = property.WithXmlDoc(
                    XmlDoc.Summary(description),
                    XmlDoc.Remarks($"Use this property to set one or more values for the parameter. Do not set both this property and ", IdentifierName(PropertyName), "."));
            }
            return(property);
        }
Example #11
0
 private static IEnumerable <MemberDeclarationSyntax> LroPartialClasses(SourceFileContext ctx, ServiceDetails svc)
 {
     if (svc.Methods.Any(m => m is MethodDetails.Lro))
     {
         // Emit partial class to give access to an LRO operations client.
         var grpcOuterCls = Class(Public | Static | Partial, svc.GrpcClientTyp.DeclaringTyp);
         using (ctx.InClass(grpcOuterCls))
         {
             var grpcInnerClass = Class(Public | Partial, svc.GrpcClientTyp);
             using (ctx.InClass(grpcInnerClass))
             {
                 var callInvoker = Property(Private, ctx.TypeDontCare, "CallInvoker");
                 var opTyp       = ctx.Type <Operations.OperationsClient>();
                 var createOperationsClientMethod = Method(Public | Virtual, opTyp, "CreateOperationsClient")()
                                                    .WithBody(New(opTyp)(callInvoker))
                                                    .WithXmlDoc(
                     XmlDoc.Summary("Creates a new instance of ", opTyp, " using the same call invoker as this client."),
                     XmlDoc.Returns("A new Operations client for the same target as this client.")
                     );
                 grpcInnerClass = grpcInnerClass.AddMembers(createOperationsClientMethod);
             }
             grpcOuterCls = grpcOuterCls.AddMembers(grpcInnerClass);
         }
         yield return(grpcOuterCls);
     }
 }
Example #12
0
        private static IEnumerable <MemberDeclarationSyntax> MixinPartialClasses(SourceFileContext ctx, ServiceDetails svc)
        {
            if (svc.Mixins.Any())
            {
                // Emit partial class to give access to clients for mixin APIs.
                // (We may well have one of these *and* an LRO partial class, but that's okay.)
                var grpcOuterCls = Class(Public | Static | Partial, svc.GrpcClientTyp.DeclaringTyp);
                using (ctx.InClass(grpcOuterCls))
                {
                    var grpcInnerClass = Class(Public | Partial, svc.GrpcClientTyp);
                    using (ctx.InClass(grpcInnerClass))
                    {
                        var callInvoker = Property(Private, ctx.TypeDontCare, "CallInvoker");

                        foreach (var mixin in svc.Mixins)
                        {
                            var grpcClientType     = ctx.Type(mixin.GrpcClientType);
                            var createClientMethod = Method(Public | Virtual, grpcClientType, "Create" + mixin.GrpcClientType.Name)()
                                                     .WithBody(New(grpcClientType)(callInvoker))
                                                     .WithXmlDoc(
                                XmlDoc.Summary("Creates a new instance of ", grpcClientType, " using the same call invoker as this client."),
                                XmlDoc.Returns("A new ", grpcClientType, " for the same target as this client.")
                                );
                            grpcInnerClass = grpcInnerClass.AddMembers(createClientMethod);
                        }
                    }
                    grpcOuterCls = grpcOuterCls.AddMembers(grpcInnerClass);
                }
                yield return(grpcOuterCls);
            }
        }
        private PropertyDeclarationSyntax GenerateProperty(SourceFileContext ctx)
        {
            var propertyType       = ctx.Type(Typ);
            var locationExpression = ctx.Type <RequestParameterType>().Access(Location.ToString());
            var property           = AutoProperty(Modifier.Public | Modifier.Virtual, propertyType, PropertyName, hasSetter: true, setterIsPrivate: IsRequired)
                                     .WithAttribute(ctx.Type <RequestParameterAttribute>())(Name, locationExpression);

            if (_schema.Description is string description)
            {
                var summary = XmlDoc.Summary(description);
                var docs    = IsRepeatedOptionalEnum
                    ? new[] { summary, XmlDoc.Remarks($"Use this property to set a single value for the parameter, or ", IdentifierName(PropertyName + "List"), " to set multiple values. Do not set both properties.") }
                    : new[] { summary };
                property = property.WithXmlDoc(docs);
            }
            return(property);
        }
                public PathElement(SourceFileContext ctx, ResourceDetails.Definition def, string rawPathElement)
                {
                    var nameWithoutId = rawPathElement.RemoveSuffix("_id");
                    var nameWithId    = $"{nameWithoutId}_id";

                    UpperCamel           = nameWithoutId.ToUpperCamelCase();
                    LowerCamel           = nameWithoutId.ToLowerCamelCase();
                    Parameter            = RoslynBuilder.Parameter(ctx.Type <string>(), nameWithId.ToLowerCamelCase());
                    ParameterWithDefault = RoslynBuilder.Parameter(ctx.Type <string>(), nameWithId.ToLowerCamelCase(), @default: Null);
                    ParameterXmlDoc      = XmlDoc.Param(Parameter, "The ", XmlDoc.C(nameWithoutId.ToUpperCamelCase()), " ID. Must not be ", null, " or empty.");
                    var summarySuffix = def.Patterns.Count > 1 ?
                                        new object[] { "May be ", null, ", depending on which resource name is contained by this instance." } :
                    new object[] { "Will not be ", null, ", unless this instance contains an unparsed resource name." };

                    Property = AutoProperty(Public, ctx.Type <string>(), nameWithId.ToUpperCamelCase())
                               .WithXmlDoc(XmlDoc.Summary(new object[] { "The ", XmlDoc.C(nameWithoutId.ToUpperCamelCase()), " ID. " }.Concat(summarySuffix).ToArray()));
                }
        public EnumMemberDeclarationSyntax GenerateDeclaration(SourceFileContext ctx)
        {
            var declaration = EnumMember(MemberName, NumericValue)
                              .WithAttribute(ctx.Type <StringValueAttribute>())(OriginalValue);

            if (Description is object)
            {
                declaration = declaration.WithXmlDoc(XmlDoc.Summary(Description));
            }
            return(declaration);
        }
        public ClassDeclarationSyntax GenerateClass(SourceFileContext ctx)
        {
            var cls = Class(Modifier.Public, Typ)
                      .WithXmlDoc(XmlDoc.Summary($"The \"{Name}\" collection of methods."));

            using (ctx.InClass(Typ))
            {
                // TODO: validate that lower camel case is the right option here.
                var resourceString = Field(Modifier.Private | Modifier.Const, ctx.Type <string>(), "Resource")
                                     .WithInitializer(Name.ToLowerCamelCase(upperAfterDigit: null));

                var service = Field(Modifier.Private | Modifier.Readonly, ctx.Type <IClientService>(), "service")
                              .WithXmlDoc(XmlDoc.Summary("The service which this resource belongs to."));

                var subresources = Subresources.Select(subresource => (property: subresource.GenerateProperty(ctx), resource: subresource));

                var ctorParameter = Parameter(ctx.Type <IClientService>(), "service");
                var ctor          = Ctor(Modifier.Public, cls)(ctorParameter)
                                    .WithBlockBody(
                    new[] { service.AssignThisQualified(ctorParameter) }
                    .Concat(subresources.Select(pair => pair.property.Assign(New(ctx.Type(pair.resource.Typ))(ctorParameter))))
                    .ToArray()
                    )
                                    .WithXmlDoc(XmlDoc.Summary("Constructs a new resource."));

                cls = cls.AddMembers(resourceString, service, ctor);

                foreach (var subresourceProperty in subresources)
                {
                    cls = cls.AddMembers(subresourceProperty.property, subresourceProperty.resource.GenerateClass(ctx));
                }

                foreach (var method in Methods)
                {
                    cls = cls.AddMembers(method.GenerateDeclarations(ctx).ToArray());
                }
            }
            return(cls);
        }
Example #17
0
        public ClassDeclarationSyntax GenerateClass(SourceFileContext ctx)
        {
            var cls = Class(Modifier.Public, Typ, Parent is null ? new[] { ctx.Type <IDirectResponseSchema>() } : Array.Empty <TypeSyntax>());

            using (ctx.InClass(Typ))
            {
                if (_schema.Description is string description)
                {
                    cls = cls.WithXmlDoc(XmlDoc.Summary(description));
                }
                cls = cls.AddMembers(Properties.SelectMany(p => p.GeneratePropertyDeclarations(ctx)).ToArray());

                // Top-level data models automatically have an etag property if one isn't otherwise generated.
                if (Parent is null && !Properties.Any(p => p.Name == "etag"))
                {
                    var etag = AutoProperty(Modifier.Public | Modifier.Virtual, ctx.Type <string>(), "ETag", hasSetter: true)
                               .WithXmlDoc(XmlDoc.Summary("The ETag of the item."));
                    cls = cls.AddMembers(etag);
                }

                cls = cls.AddMembers(Properties.SelectMany(p => p.GenerateAnonymousModels(ctx)).ToArray());
            }
            return(cls);
        }
Example #18
0
        private static ClassDeclarationSyntax GenerateClass(string ns, SourceFileContext ctx, IEnumerable <FileDescriptor> packageFileDescriptors)
        {
            var typ = Typ.Manual(ns, ClassName);
            var cls = Class(Internal | Static, typ)
                      .WithXmlDoc(XmlDoc.Summary("Static class to provide common access to package-wide API metadata."));

            var yieldStatements      = packageFileDescriptors.Select(GenerateYieldStatement).ToArray();
            var fileDescriptorMethod = Method(Private | Static, ctx.Type(Typ.Of <IEnumerable <FileDescriptor> >()), "GetFileDescriptors")()
                                       .WithBlockBody(yieldStatements);

            var apiMetadataType = ctx.Type <ApiMetadata>();
            var property        = AutoProperty(Internal | Static, apiMetadataType, PropertyName)
                                  .WithInitializer(New(apiMetadataType)(ns, IdentifierName(fileDescriptorMethod.Identifier)))
                                  .WithXmlDoc(XmlDoc.Summary("The ", apiMetadataType, " for services in this package."));

            return(cls.AddMembers(property, fileDescriptorMethod));

            YieldStatementSyntax GenerateYieldStatement(FileDescriptor descriptor)
            {
                var type = ctx.Type(ProtoTyp.OfReflectionClass(descriptor));

                return(YieldStatement(SyntaxKind.YieldReturnStatement, type.Access("Descriptor")));
            }
        }
Example #19
0
        private static MemberDeclarationSyntax PaginatedPartialInterfaceClass(SourceFileContext ctx, Typ typ, MessageDescriptor messageDesc)
        {
            var partialInterfaceCls = Class(Public | Partial, typ, baseTypes: ctx.Type <IPageRequest>());

            if (messageDesc.FindFieldByName("page_size") is null)
            {
                //DiREGapic scenario where `max_results` is an option for a page size-semantic field.
                var maxResMessage = messageDesc.FindFieldByName("max_results");
                if (maxResMessage is null)
                {
                    throw new InvalidOperationException("Paginated request should have either page_size or max_results field.");
                }

                using (ctx.InClass(partialInterfaceCls))
                {
                    var underlyingProperty = Property(DontCare, ctx.TypeDontCare, "MaxResults");

                    var getBody = ProtoTyp.Of(maxResMessage) == Typ.Of <int>()
                        ? Return(underlyingProperty)
                        : Return(CheckedCast(ctx.Type <int>(), underlyingProperty));

                    var assignFrom = ProtoTyp.Of(maxResMessage) == Typ.Of <int>()
                        ? Value
                        : CheckedCast(ctx.Type(ProtoTyp.Of(maxResMessage)), Value);
                    var setBody = underlyingProperty.Assign(assignFrom);

                    var property = Property(Public, ctx.Type <int>(), "PageSize")
                                   .WithGetBody(getBody)
                                   .WithSetBody(setBody)
                                   .WithXmlDoc(XmlDoc.InheritDoc);
                    partialInterfaceCls = partialInterfaceCls.AddMembers(property);
                }
            }

            return(partialInterfaceCls);
        }
 public PatternDetails(SourceFileContext ctx, ResourceDetails.Definition def, ResourceDetails.Definition.Pattern pattern)
 {
     PatternString = pattern.PatternString;
     PathSegments  = pattern.Template.Segments.Select(x => new PathSegment(ctx, def, x)).ToList();
     if (pattern.Template.ParameterNames.Count() == 0)
     {
         // Path-template contains no parameters, special naming required.
         UpperName = PatternString.ToUpperCamelCase();
         LowerName = PatternString.ToLowerCamelCase();
     }
     else
     {
         // Standard naming, concat all parameter names.
         UpperName = string.Join("", PathElements.Select(x => x.UpperCamel));
         LowerName = string.Join("", PathElements.Take(1).Select(x => x.LowerCamel).Concat(PathElements.Skip(1).Select(x => x.UpperCamel)));
     }
     PathTemplateField = Field(Private | Static, ctx.Type <PathTemplate>(), $"s_{LowerName}").WithInitializer(New(ctx.Type <PathTemplate>())(pattern.Template.PathTemplateString));
 }
        internal object GenerateInitializer(SourceFileContext ctx)
        {
            var parameterCtor = New(ctx.Type <Google.Apis.Discovery.Parameter>())()
                                .WithInitializer(
                new ObjectInitExpr("Name", Name),
                new ObjectInitExpr("IsRequired", IsRequired),
                new ObjectInitExpr("ParameterType", _schema.Location),
                new ObjectInitExpr("DefaultValue", string.IsNullOrEmpty(_schema.Default__) ? (object)Null : _schema.Default__),
                new ObjectInitExpr("Pattern", PatternCode(_schema.Pattern)));

            return(IdentifierName("RequestParameters").Call("Add")(Name, parameterCtor));

            object PatternCode(string pattern)
            {
                if (pattern is null)
                {
                    return(Null);
                }
                // Escape double-quotes to "double double-quotes".
                var escaped = pattern.Replace("\"", "\"\"");

                return(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal($"@\"{escaped}\"", pattern)));
            }
        }
Example #22
0
        private static IEnumerable <MemberDeclarationSyntax> LroPartialClasses(SourceFileContext ctx, ServiceDetails svc)
        {
            if (svc.Methods.Any(m => m is MethodDetails.StandardLro))
            {
                // Emit partial class to give access to an LRO operations client.
                var grpcOuterCls = Class(Public | Static | Partial, svc.GrpcClientTyp.DeclaringTyp);
                using (ctx.InClass(grpcOuterCls))
                {
                    var grpcInnerClass = Class(Public | Partial, svc.GrpcClientTyp);
                    using (ctx.InClass(grpcInnerClass))
                    {
                        var callInvoker = Property(Private, ctx.TypeDontCare, "CallInvoker");
                        var opTyp       = ctx.Type <Operations.OperationsClient>();
                        var createOperationsClientMethod = Method(Public | Virtual, opTyp, "CreateOperationsClient")()
                                                           .WithBody(New(opTyp)(callInvoker))
                                                           .WithXmlDoc(
                            XmlDoc.Summary("Creates a new instance of ", opTyp, " using the same call invoker as this client."),
                            XmlDoc.Returns("A new Operations client for the same target as this client.")
                            );
                        grpcInnerClass = grpcInnerClass.AddMembers(createOperationsClientMethod);
                    }
                    grpcOuterCls = grpcOuterCls.AddMembers(grpcInnerClass);
                }
                yield return(grpcOuterCls);
            }

            // Generate partial classes to delegate to other services handling operations
            if (svc.Methods.Any(m => m is MethodDetails.NonStandardLro))
            {
                var operationServices = svc.Methods.OfType <MethodDetails.NonStandardLro>().Select(lro => lro.OperationService).Distinct().ToList();

                // Emit partial class to give access to an LRO operations client.
                var grpcOuterCls = Class(Public | Static | Partial, svc.GrpcClientTyp.DeclaringTyp);
                using (ctx.InClass(grpcOuterCls))
                {
                    var grpcInnerClass = Class(Public | Partial, svc.GrpcClientTyp);
                    using (ctx.InClass(grpcInnerClass))
                    {
                        var callInvoker = Property(Private, ctx.TypeDontCare, "CallInvoker");
                        var opTyp       = ctx.Type <Operations.OperationsClient>();

                        foreach (var operationService in operationServices)
                        {
                            var grpcClient = ctx.Type(Typ.Nested(Typ.Manual(ctx.Namespace, operationService), $"{operationService}Client"));
                            var createOperationsClientMethod = Method(Public | Virtual, opTyp, $"CreateOperationsClientFor{operationService}")()
                                                               .WithBody(grpcClient.Call("CreateOperationsClient")(callInvoker))
                                                               .WithXmlDoc(
                                XmlDoc.Summary("Creates a new instance of ", opTyp, $" using the same call invoker as this client, delegating to {operationService}."),
                                XmlDoc.Returns("A new Operations client for the same target as this client.")
                                );
                            grpcInnerClass = grpcInnerClass.AddMembers(createOperationsClientMethod);
                        }
                    }
                    grpcOuterCls = grpcOuterCls.AddMembers(grpcInnerClass);
                }
                yield return(grpcOuterCls);
            }

            // Generate partial classes for the operation-handling services
            if (svc.NonStandardLro is ServiceDetails.NonStandardLroDetails lroDetails)
            {
                // Emit partial class to give access to an LRO operations client.
                var grpcOuterCls = Class(Public | Static | Partial, svc.GrpcClientTyp.DeclaringTyp);
                using (ctx.InClass(grpcOuterCls))
                {
                    var grpcInnerClass = Class(Public | Partial, svc.GrpcClientTyp);
                    using (ctx.InClass(grpcInnerClass))
                    {
                        var callInvoker                  = Parameter(ctx.Type <CallInvoker>(), "callInvoker");
                        var request                      = Parameter(ctx.TypeDontCare, "request");
                        var response                     = Parameter(ctx.TypeDontCare, "response");
                        var opTyp                        = ctx.Type <Operations.OperationsClient>();
                        var forwardingCallInvoker        = Local(ctx.Type <CallInvoker>(), "forwardingCallInvoker");
                        var createOperationsClientMethod = Method(Internal | Static, opTyp, "CreateOperationsClient")(callInvoker)
                                                           .WithBody(
                            forwardingCallInvoker.WithInitializer(
                                // Note: can't use Typ.Of<ForwardingCallInvoker<GetOperationRequest>> as it's a static class.
                                ctx.Type(Typ.Generic(Typ.Of(typeof(ForwardingCallInvoker <>)), Typ.Of <GetOperationRequest>())).Call("Create")(
                                    callInvoker,
                                    "/google.longrunning.Operations/GetOperation",
                                    Property(Private, ctx.TypeDontCare, $"__Method_{lroDetails.PollingMethod.Name}"),
                                    ctx.Type(lroDetails.PollingRequestTyp).Access("ParseLroRequest"),     // Method group conversion
                                    Lambda(request, response)(response.Call("ToLroResponse")(request.Access("Name")))
                                    )),
                            Return(New(opTyp)(forwardingCallInvoker)))
                                                           .WithXmlDoc(
                            XmlDoc.Summary(
                                "Creates a new instance of ", opTyp, "using the specified call invoker, but ",
                                $"redirecting Google.LongRunning RPCs to {lroDetails.Service.Name} RPCs."),
                            XmlDoc.Returns("A new Operations client for the same target as this client.")
                            );
                        grpcInnerClass = grpcInnerClass.AddMembers(createOperationsClientMethod);
                    }
                    grpcOuterCls = grpcOuterCls.AddMembers(grpcInnerClass);
                }
                yield return(grpcOuterCls);
            }
        }
Example #23
0
        public static MethodDeclarationSyntax ModifyBidiRequestCallSettingsPartialMethod(SourceFileContext ctx, MethodDetails.BidiStreaming method)
        {
            var settingsParam = Parameter(ctx.Type <CallSettings>(), "settings").Ref();

            return(PartialMethod(method.ModifyStreamingCallSettingsMethodName)(settingsParam));
        }
Example #24
0
 private object InitExpr(MethodDetails.Signature.Field field, ParameterSyntax param, ResourceDetails.Field treatAsResource = null)
 {
     // Type                  | Single optional | Single required | Repeated optional | Repeated required
     // ----------------------|-----------------|-----------------|-------------------|------------------
     // Primitive & enum      | nothing to do   | nothing to do   | null -> empty     | check not null
     // string                | null -> ""      | check not empty | null -> empty     | check not null
     // bytes                 | null -> byte[0] | check not null  | null -> empty     | check not null
     // message               | null ok         | check not null  | null -> empty     | check not null
     // resourcename (string) | null -> ""      | check not null  | null -> empty     | check not null
     // resourcenames use the generated partial resource-name-type properties, which perform the string conversion.
     if (field.IsMap)
     {
         return(CollectionInitializer(field.IsRequired ?
                                      Ctx.Type(typeof(GaxPreconditions)).Call(nameof(GaxPreconditions.CheckNotNull))(param, Nameof(param)) :
                                      param.NullCoalesce(New(Ctx.Type(Typ.Generic(typeof(Dictionary <,>),
                                                                                  field.Typ.GenericArgTyps.First(), field.Typ.GenericArgTyps.ElementAt(1))))())));
     }
     else if (field.IsRepeated)
     {
         if (treatAsResource is object)
         {
             return(CollectionInitializer(field.IsRequired ?
                                          Ctx.Type(typeof(GaxPreconditions)).Call(nameof(GaxPreconditions.CheckNotNull))(param, Nameof(param)) :
                                          param.NullCoalesce(Ctx.Type(typeof(Enumerable)).Call(
                                                                 nameof(Enumerable.Empty), Ctx.Type(treatAsResource.ResourceDefinition.ResourceNameTyp))())));
         }
         else
         {
             return(CollectionInitializer(field.IsRequired ?
                                          Ctx.Type(typeof(GaxPreconditions)).Call(nameof(GaxPreconditions.CheckNotNull))(param, Nameof(param)) :
                                          param.NullCoalesce(Ctx.Type(typeof(Enumerable)).Call(nameof(Enumerable.Empty), Ctx.Type(field.Typ.GenericArgTyps.First()))())));
         }
     }
     else
     {
         if (treatAsResource is object)
         {
             return(field.IsRequired ?
                    Ctx.Type(typeof(GaxPreconditions)).Call(nameof(GaxPreconditions.CheckNotNull))(param, Nameof(param)) :
                    (object)param);
         }
         else if (field.Typ.IsPrimitive || field.Typ.IsEnum)
         {
             return(param);
         }
         else if (field.Typ.FullName == typeof(string).FullName)
         {
             return(field.IsRequired ?
                    Ctx.Type(typeof(GaxPreconditions)).Call(
                        field.IsWrapperType ? nameof(GaxPreconditions.CheckNotNull) : nameof(GaxPreconditions.CheckNotNullOrEmpty))(
                        param, Nameof(param)) :
                    field.IsWrapperType?param : (object)param.NullCoalesce(""));
         }
         else if (field.Typ.FullName == typeof(ByteString).FullName)
         {
             return(field.IsRequired ?
                    Ctx.Type(typeof(GaxPreconditions)).Call(nameof(GaxPreconditions.CheckNotNull))(param, Nameof(param)) :
                    field.IsWrapperType?param : (object)param.NullCoalesce(Ctx.Type <ByteString>().Access(nameof(ByteString.Empty))));
         }
         else if (field.IsWrapperType)
         {
             return(field.IsRequired ?
                    param.NullCoalesce(Throw(New(Ctx.Type <ArgumentNullException>())(Nameof(param)))) :
                    (object)param);
         }
         else
         {
             return(field.IsRequired ?
                    Ctx.Type(typeof(GaxPreconditions)).Call(nameof(GaxPreconditions.CheckNotNull))(param, Nameof(param)) :
                    (object)param);
         }
     }
 }
Example #25
0
 public MethodDeclarationSyntax GenerateMethodDeclaration(SourceFileContext ctx)
 {
     return(Method(Modifier.Public, ctx.Type <string>(), Name)());
 }
Example #26
0
        public ClassDeclarationSyntax GenerateServiceClass(SourceFileContext ctx)
        {
            var cls = Class(Modifier.Public, ServiceTyp, ctx.Type <BaseClientService>()).WithXmlDoc(XmlDoc.Summary($"The {ClassName} Service."));

            using (ctx.InClass(cls))
            {
                var discoveryVersionTyp = Typ.Manual("Google.Apis.Discovery", "DiscoveryVersion");
                var version             = Field(Modifier.Public | Modifier.Const, ctx.Type <string>(), "Version")
                                          .WithInitializer(ApiVersion)
                                          .WithXmlDoc(XmlDoc.Summary("The API version."));
                var discoveryVersion = Field(Modifier.Public | Modifier.Static, ctx.Type(discoveryVersionTyp), "DiscoveryVersionUsed")
                                       .WithInitializer(ctx.Type(discoveryVersionTyp).Access(nameof(DiscoveryVersion.Version_1_0)))
                                       .WithXmlDoc(XmlDoc.Summary("The discovery version used to generate this service."));

                var parameterlessCtor = Ctor(Modifier.Public, cls, ThisInitializer(New(ctx.Type <BaseClientService.Initializer>())()))()
                                        .WithBody()
                                        .WithXmlDoc(XmlDoc.Summary("Constructs a new service."));

                var initializerParam = Parameter(ctx.Type <BaseClientService.Initializer>(), "initializer");

                var featuresArrayInitializer = ApiFeatures.Any()
                    ? NewArray(ctx.ArrayType(Typ.Of <string[]>()))(ApiFeatures.ToArray())
                    : NewArray(ctx.ArrayType(Typ.Of <string[]>()), LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(0)));
                var features = Property(Modifier.Public | Modifier.Override, ctx.Type <IList <string> >(), "Features")
                               .WithGetBody(featuresArrayInitializer)
                               .WithXmlDoc(XmlDoc.Summary("Gets the service supported features."));

                var nameProperty = Property(Modifier.Public | Modifier.Override, ctx.Type <string>(), "Name")
                                   .WithGetBody(ApiName)
                                   .WithXmlDoc(XmlDoc.Summary("Gets the service name."));

                // Note: the following 4 properties have special handling post-generation, in terms
                // of adding the #if directives in.
                var baseUri = Property(Modifier.Public | Modifier.Override, ctx.Type <string>(), "BaseUri")
                              .WithGetBody(IdentifierName("BaseUriOverride").NullCoalesce(BaseUri))
                              .WithXmlDoc(XmlDoc.Summary("Gets the service base URI."));

                var basePath = Property(Modifier.Public | Modifier.Override, ctx.Type <string>(), "BasePath")
                               .WithGetBody(BasePath)
                               .WithXmlDoc(XmlDoc.Summary("Gets the service base path."));

                var batchUri = Property(Modifier.Public | Modifier.Override, ctx.Type <string>(), "BatchUri")
                               .WithGetBody(BatchUri)
                               .WithXmlDoc(XmlDoc.Summary("Gets the batch base URI; ", XmlDoc.C("null"), " if unspecified."));
                var batchPath = Property(Modifier.Public | Modifier.Override, ctx.Type <string>(), "BatchPath")
                                .WithGetBody(BatchPath)
                                .WithXmlDoc(XmlDoc.Summary("Gets the batch base path; ", XmlDoc.C("null"), " if unspecified."));

                var resourceProperties = Resources.Select(resource => resource.GenerateProperty(ctx)).ToArray();

                var parameterizedCtor = Ctor(Modifier.Public, cls, BaseInitializer(initializerParam))(initializerParam)
                                        .WithBlockBody(resourceProperties.Zip(Resources).Select(pair => pair.First.Assign(New(ctx.Type(pair.Second.Typ))(This))).ToArray())
                                        .WithXmlDoc(
                    XmlDoc.Summary("Constructs a new service."),
                    XmlDoc.Param(initializerParam, "The service initializer."));

                cls = cls.AddMembers(version, discoveryVersion, parameterlessCtor, parameterizedCtor, features, nameProperty, baseUri, basePath, batchUri, batchPath);

                if (AuthScopes.Any())
                {
                    var scopeClass = Class(Modifier.Public, Typ.Manual(PackageName, "Scope"))
                                     .WithXmlDoc(XmlDoc.Summary($"Available OAuth 2.0 scopes for use with the {Title}."));
                    using (ctx.InClass(scopeClass))
                    {
                        foreach (var scope in AuthScopes)
                        {
                            var field = Field(Modifier.Public | Modifier.Static, ctx.Type <string>(), scope.Name)
                                        .WithInitializer(scope.Value)
                                        .WithXmlDoc(XmlDoc.Summary(scope.Description));
                            scopeClass = scopeClass.AddMembers(field);
                        }
                    }

                    var scopeConstantsClass = Class(Modifier.Public | Modifier.Static, Typ.Manual(PackageName, "ScopeConstants"))
                                              .WithXmlDoc(XmlDoc.Summary($"Available OAuth 2.0 scope constants for use with the {Title}."));
                    using (ctx.InClass(scopeConstantsClass))
                    {
                        foreach (var scope in AuthScopes)
                        {
                            var field = Field(Modifier.Public | Modifier.Const, ctx.Type <string>(), scope.Name)
                                        .WithInitializer(scope.Value)
                                        .WithXmlDoc(XmlDoc.Summary(scope.Description));
                            scopeConstantsClass = scopeConstantsClass.AddMembers(field);
                        }
                    }

                    cls = cls.AddMembers(scopeClass, scopeConstantsClass);
                }

                // TODO: Find an example of this...
                foreach (var method in Methods)
                {
                    cls = cls.AddMembers(method.GenerateDeclarations(ctx).ToArray());
                }

                cls = cls.AddMembers(resourceProperties);
            }
            return(cls);
        }
Example #27
0
        private IEnumerable <MemberDeclarationSyntax> GenerateUploadMembers(SourceFileContext ctx)
        {
            var uploadTyp = Typ.Nested(ctx.CurrentTyp, PascalCasedName + "MediaUpload");

            var baseTypArgument1 = BodyTyp ?? Typ.Of <string>();
            var baseTyp          = _restMethod.Response is object
                                   ?Typ.Generic(Typ.Of(typeof(ResumableUpload <,>)), baseTypArgument1, ResponseTyp)
                                       : Typ.Generic(Typ.Of(typeof(ResumableUpload <>)), baseTypArgument1);

            var uploadCls = Class(Modifier.Public, uploadTyp, ctx.Type(baseTyp))
                            .WithXmlDoc(XmlDoc.Summary($"{PascalCasedName} media upload which supports resumable upload."));

            var parameters         = CreateParameterList(uploadTyp);
            var requiredParameters = parameters
                                     .TakeWhile(p => p.IsRequired)
                                     .Select(p => (param: p, decl: Parameter(ctx.Type(p.Typ), p.CodeParameterName)))
                                     .ToList();

            var insertMethodParameters = new List <ParameterSyntax>();

            if (BodyTyp is object)
            {
                insertMethodParameters.Add(Parameter(ctx.Type(BodyTyp), "body"));
            }
            insertMethodParameters.AddRange(requiredParameters.Select(pair => pair.decl));
            var streamParam = Parameter(ctx.Type <Stream>(), "stream");

            var contentTypeParam = Parameter(ctx.Type <string>(), "contentType");

            insertMethodParameters.Add(streamParam);
            insertMethodParameters.Add(contentTypeParam);

            // This doc comment is common between the method and the constructor.
            var remarks = XmlDoc.Remarks("Considerations regarding ", streamParam, ":",
                                         XmlDoc.BulletListOfItemNodes(
                                             XmlDoc.Item("If ", streamParam, " is seekable, then the stream position will be reset to ", 0, " before reading commences. If ", streamParam, " is not seekable, then it will be read from its current position"),
                                             XmlDoc.Item("Caller is responsible for maintaining the ", streamParam, " open until the upload is completed"),
                                             XmlDoc.Item("Caller is responsible for closing the ", streamParam)));

            var methodDocComments = new List <DocumentationCommentTriviaSyntax>
            {
                XmlDoc.Summary(_restMethod.Description),
                remarks
            };

            if (BodyTyp is object)
            {
                methodDocComments.Add(XmlDoc.Param(Parameter(ctx.Type(BodyTyp), "body"), "The body of the request."));
            }

            methodDocComments.AddRange(requiredParameters.Select(pair => XmlDoc.Param(pair.decl, pair.param.Description)));
            methodDocComments.Add(XmlDoc.Param(streamParam, "The stream to upload. See remarks for further information."));
            methodDocComments.Add(XmlDoc.Param(contentTypeParam, "The content type of the stream to upload."));

            // We're taking it from the field in the parent type, but it becomes a parameter for the constructor...
            // So long as it appears as "service" we don't really mind.
            var serviceParam   = Parameter(ctx.Type <IClientService>(), "service");
            var ctorParameters = new List <ParameterSyntax> {
                serviceParam
            };

            ctorParameters.AddRange(insertMethodParameters);

            var insertMethod = Method(Modifier.Public | Modifier.Virtual, ctx.Type(uploadTyp), PascalCasedName)(insertMethodParameters.ToArray())
                               .WithBlockBody(Return(New(ctx.Type(uploadTyp))(ctorParameters)))
                               .WithXmlDoc(methodDocComments.ToArray());

            using (ctx.InClass(uploadTyp))
            {
                var baseInitializerArgs = new List <object>
                {
                    serviceParam,
                    ctx.Type <string>().Call(nameof(string.Format))("/{0}/{1}{2}", "upload", serviceParam.Access("BasePath"), _restMethod.Path),
                    _restMethod.HttpMethod,
                    streamParam,
                    contentTypeParam
                };
                var baseInitializer = BaseInitializer(baseInitializerArgs).WithAdditionalAnnotations(Annotations.LineBreakAnnotation);
                var assignments     = requiredParameters.Select(p => Field(0, ctx.Type(p.param.Typ), p.param.PropertyName).Assign(p.decl)).ToList();

                if (BodyTyp is object)
                {
                    // The Body property is in the base class.
                    var bodyProperty = Property(Modifier.Public, ctx.Type(BodyTyp), "Body");
                    assignments.Add(bodyProperty.Assign(Parameter(ctx.Type(BodyTyp), "body")));
                }

                // The parameters to the constructor are the same as for the method.
                var uploadCtor = Ctor(Modifier.Public, uploadCls, baseInitializer)(ctorParameters.ToArray())
                                 .WithBlockBody(assignments)
                                 .WithXmlDoc(XmlDoc.Summary($"Constructs a new {PascalCasedName} media upload instance."), remarks);

                uploadCls = uploadCls.AddMembers(Package.CreateParameterList(uploadTyp).SelectMany(p => p.GenerateDeclarations(ctx)).ToArray());
                uploadCls = uploadCls.AddMembers(parameters.SelectMany(p => p.GenerateDeclarations(ctx)).ToArray());
                uploadCls = uploadCls.AddMembers(uploadCtor);
            }

            yield return(insertMethod);

            yield return(uploadCls);
        }
Example #28
0
        private static ClassDeclarationSyntax AddMediaDownloadMethods(PropertyDeclarationSyntax mediaDownloader, ClassDeclarationSyntax cls, SourceFileContext ctx)
        {
            var stream                       = Parameter(ctx.Type <Stream>(), "stream");
            var cancellationToken            = Parameter(ctx.Type <CancellationToken>(), "cancellationToken");
            var cancellationTokenWithDefault = Parameter(ctx.Type <CancellationToken>(), "cancellationToken", DefaultExpression(ctx.Type <CancellationToken>()));
            var range = Parameter(ctx.Type <RangeHeaderValue>(), "range");

            var syncDownloadWithStatus = Method(Modifier.Public | Modifier.Virtual, ctx.Type <IDownloadProgress>(), "DownloadWithStatus")(stream)
                                         .WithBlockBody(Return(mediaDownloader.Call("Download")(ThisQualifiedCall("GenerateRequestUri")(), stream)))
                                         .WithXmlDoc(
                XmlDoc.Summary("Synchronously download the media into the given stream."),
                XmlDoc.Returns("The final status of the download; including whether the download succeeded or failed."));

            var syncDownload = Method(Modifier.Public | Modifier.Virtual, ctx.Type(Typ.Void), "Download")(stream)
                               .WithBlockBody(mediaDownloader.Call("Download")(ThisQualifiedCall("GenerateRequestUri")(), stream))
                               .WithXmlDoc(XmlDoc.Summary(
                                               XmlDoc.Para("Synchronously download the media into the given stream."),
                                               XmlDoc.Para("Warning: This method hides download errors; use ", syncDownloadWithStatus, " instead.")));

            var asyncDownloadNoToken = Method(Modifier.Public | Modifier.Virtual, ctx.Type <Task <IDownloadProgress> >(), "DownloadAsync")(stream)
                                       .WithBlockBody(Return(mediaDownloader.Call("DownloadAsync")(ThisQualifiedCall("GenerateRequestUri")(), stream)))
                                       .WithXmlDoc(XmlDoc.Summary("Asynchronously download the media into the given stream."));

            var asyncDownloadWithToken = Method(Modifier.Public | Modifier.Virtual, ctx.Type <Task <IDownloadProgress> >(), "DownloadAsync")(stream, cancellationToken)
                                         .WithParameterLineBreaks()
                                         .WithBlockBody(Return(mediaDownloader.Call("DownloadAsync")(ThisQualifiedCall("GenerateRequestUri")(), stream, cancellationToken)))
                                         .WithXmlDoc(XmlDoc.Summary("Asynchronously download the media into the given stream."));

            var mediaDownloaderLocal = Local(ctx.Type(Typ.Var), "mediaDownloader")
                                       .WithInitializer(New(ctx.Type <MediaDownloader>())(Property(0, ctx.Type <IClientService>(), "Service")));
            var syncRange = Method(Modifier.Public | Modifier.Virtual, ctx.Type <IDownloadProgress>(), "DownloadRange")(stream, range)
                            .WithBlockBody(
                mediaDownloaderLocal,
                mediaDownloaderLocal.Access("Range").Assign(range),
                Return(mediaDownloaderLocal.Call("Download")(ThisQualifiedCall("GenerateRequestUri")(), stream)))
                            .WithXmlDoc(XmlDoc.Summary("Synchronously download a range of the media into the given stream."));

            var asyncRange = Method(Modifier.Public | Modifier.Virtual, ctx.Type <Task <IDownloadProgress> >(), "DownloadRangeAsync")(stream, range, cancellationTokenWithDefault)
                             .WithParameterLineBreaks()
                             .WithBlockBody(
                mediaDownloaderLocal,
                mediaDownloaderLocal.Access("Range").Assign(range),
                Return(mediaDownloaderLocal.Call("DownloadAsync")(ThisQualifiedCall("GenerateRequestUri")(), stream, cancellationTokenWithDefault)))
                             .WithXmlDoc(XmlDoc.Summary("Asynchronously download a range of the media into the given stream."));

            return(cls.AddMembers(syncDownload, syncDownloadWithStatus, asyncDownloadNoToken, asyncDownloadWithToken, syncRange, asyncRange));
        }
            public ClassDeclarationSyntax Generate()
            {
                var cls = Class(Public | Sealed | Partial, _def.ResourceNameTyp, _ctx.Type <IResourceName>(), _ctx.Type(Typ.Generic(typeof(IEquatable <>), _def.ResourceNameTyp)))
                          .WithXmlDoc(XmlDoc.Summary("Resource name for the ", XmlDoc.C(_def.DocName), " resource."));

                using (_ctx.InClass(cls))
                {
                    cls = cls.AddMembers(ResourceTypeEnum());
                    cls = cls.AddMembers(TemplateFields().ToArray());
                    cls = cls.AddMembers(FromUnparsedMethod());
                    cls = cls.AddMembers(FromMethods().ToArray());
                    cls = cls.AddMembers(FormatMethods().ToArray());
                    cls = cls.AddMembers(ParseMethods().ToArray());
                    cls = cls.AddMembers(Constructors(cls).ToArray());
                    cls = cls.AddMembers(ResourceType());
                    cls = cls.AddMembers(UnparsedResourceNameProperty());
                    cls = cls.AddMembers(Properties().ToArray());
                    cls = cls.AddMembers(IsKnownPattern());
                    cls = cls.AddMembers(ToString());
                    cls = cls.AddMembers(GetHashCode());
                    cls = cls.AddMembers(Equals());
                    cls = cls.AddMembers(EqualsIEquatable());
                    cls = cls.AddMembers(EqualityOperator());
                    cls = cls.AddMembers(InequalityOperator());
                }
                return(cls);
            }
Example #30
0
 public static FieldDeclarationSyntax ApiCallField(SourceFileContext ctx, MethodDetails method) =>
 Field(Private | Readonly, ctx.Type(method.ApiCallTyp), method.ApiCallFieldName);