public void TestGetParameterTypeReference()
        {
            MockParameter param = new MockParameter()
            {
                Name = "Parameter"
            };
            CodeTypeDeclaration decl = new CodeTypeDeclaration();
            CodeTypeReference   refType;

            param.IsRequired = true;

            // Normal string.
            param.ValueType = "string";
            refType         = ResourceBaseGenerator.GetParameterTypeReference(decl, param);
            Assert.AreEqual(typeof(string).FullName, refType.BaseType);

            // Normal int
            param.ValueType = "integer";
            refType         = ResourceBaseGenerator.GetParameterTypeReference(decl, param);
            Assert.AreEqual(typeof(long).FullName, refType.BaseType);

            // optional int
            param.IsRequired = false;
            param.ValueType  = "integer";
            refType          = ResourceBaseGenerator.GetParameterTypeReference(decl, param);
            Assert.AreEqual(typeof(Nullable <>).FullName, refType.BaseType);
            Assert.AreEqual(1, refType.TypeArguments.Count);
            Assert.AreEqual(typeof(Int64).FullName, refType.TypeArguments[0].BaseType);

            // Enumeration
            param.IsRequired            = true;
            param.ValueType             = "string";
            param.EnumValues            = new[] { "TestA", "TestB" };
            param.EnumValueDescriptions = new[] { "DescA", "DescB" };
            decl.Members.Add(EnumResourceDecorator.GenerateEnum(
                                 decl, "TestEnum", null, param.EnumValues, param.EnumValueDescriptions));
            refType = ResourceBaseGenerator.GetParameterTypeReference(decl, param);
            Assert.AreEqual("TestEnum", refType.BaseType);

            // Optional enumeration
            param.IsRequired            = false;
            param.ValueType             = "string";
            param.EnumValues            = new[] { "TestA", "TestB" };
            param.EnumValueDescriptions = new[] { "DescA", "DescB" };
            refType = ResourceBaseGenerator.GetParameterTypeReference(decl, param);
            Assert.AreEqual(typeof(Nullable <>).FullName, refType.BaseType);
            Assert.AreEqual(1, refType.TypeArguments.Count);
            Assert.AreEqual("TestEnum", refType.TypeArguments[0].BaseType);
        }
        internal void AddRequestParameters(CodeTypeDeclaration resourceClass,
                                           IMethod request,
                                           CodeConstructor constructor,
                                           bool addOptional)
        {
            if (request.Parameters == null)
            {
                return; // Nothing to do here.
            }

            foreach (IParameter parameter in request.GetAllParametersSorted())
            {
                if (!addOptional && !parameter.IsRequired)
                {
                    continue;
                }

                // Retrieve parameter name and type.
                string            name = parameter.Name;
                CodeTypeReference type = ResourceBaseGenerator.GetParameterTypeReference(
                    resourceClass, parameter);

                // Generate valid names for the parameter and the field.
                IEnumerable <string> usedWords = from IParameter p in request.Parameters.Values select p.Name;
                string parameterName           = GeneratorUtils.GetParameterName(parameter, usedWords.Without(parameter.Name));
                string fieldName = GeneratorUtils.GetFieldName(name, Enumerable.Empty <string>());

                // Add the constructor parameter. (e.g. JsonSchema schema)
                var newParameter = new CodeParameterDeclarationExpression(type, parameterName);
                constructor.Parameters.Add(newParameter);

                // Make the parameter optional if required.
                if (!parameter.IsRequired)
                {
                    var optionalTypeRef = new CodeTypeReference(typeof(OptionalAttribute));
                    newParameter.CustomAttributes.Add(new CodeAttributeDeclaration(optionalTypeRef));
                }

                // Add the initialization expression (e.g. this.schema = schema;)
                var initStatement = new CodeAssignStatement();
                initStatement.Left  = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldName);
                initStatement.Right = new CodeVariableReferenceExpression(parameterName);
                constructor.Statements.Add(initStatement);
            }
        }
        internal CodeTypeMemberCollection GenerateParameterProperty(IDiscoveryParameter parameter,
                                                                    IMethod method,
                                                                    CodeTypeDeclaration resourceClass,
                                                                    IEnumerable <string> usedNames)
        {
            // Get the name and return type of this parameter.
            string            name       = parameter.Name;
            CodeTypeReference returnType = ResourceBaseGenerator.GetParameterTypeReference(
                resourceClass, parameter);

            // Generate the property and field.
            CodeTypeMemberCollection newMembers = DecoratorUtil.CreateAutoProperty(
                name, parameter.Description, returnType, usedNames, parameter.IsRequired, null);

            // Add the KeyAttribute to the property.
            foreach (CodeTypeMember member in newMembers)
            {
                CodeMemberProperty property = member as CodeMemberProperty;
                if (property == null)
                {
                    continue;
                }

                RequestParameterType requestParameterType =
                    parameter.ParameterType == PathParameter ? RequestParameterType.Path : RequestParameterType.Query;

                // Declare the RequestParameter attribute.
                CodeTypeReference attributeType = new CodeTypeReference(typeof(RequestParameterAttribute));

                // Generates something like..
                // [Google.Apis.Util.RequestParameterAttribute("prettyPrint",
                //   Google.Apis.Util.RequestParameterType.Query)]
                CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(attributeType);
                attribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(parameter.Name)));
                attribute.Arguments.Add(
                    new CodeAttributeArgument(
                        new CodeFieldReferenceExpression(
                            new CodeTypeReferenceExpression(typeof(RequestParameterType)),
                            Enum.GetName(typeof(RequestParameterType), requestParameterType))));
                property.CustomAttributes.Add(attribute);
            }

            return(newMembers);
        }