// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"go/format"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"time"
	"unicode"

	"google.golang.org/api/google-api-go-generator/internal/disco"
)

const (
	googleDiscoveryURL = "https://www.googleapis.com/discovery/v1/apis"
	generatorVersion   = "2018018"
)

var (
	apiToGenerate = flag.String("api", "*", "The API ID to generate, like 'tasks:v1'. A value of '*' means all.")
	useCache      = flag.Bool("cache", true, "Use cache of discovered Google API discovery documents.")
	genDir        = flag.String("gendir", "", "Directory to use to write out generated Go files")
	build         = flag.Bool("build", false, "Compile generated packages.")
	install       = flag.Bool("install", false, "Install generated packages.")
	apisURL       = flag.String("discoveryurl", googleDiscoveryURL, "URL to root discovery document")

	publicOnly = flag.Bool("publiconly", true, "Only build public, released APIs. Only applicable for Google employees.")

	jsonFile       = flag.String("api_json_file", "", "If non-empty, the path to a local file on disk containing the API to generate. Exclusive with setting --api.")
	output         = flag.String("output", "", "(optional) Path to source output file. If not specified, the API name and version are used to construct an output path (e.g. tasks/v1).")
	apiPackageBase = flag.String("api_pkg_base", "google.golang.org/api", "Go package prefix to use for all generated APIs.")
	baseURL        = flag.String("base_url", "", "(optional) Override the default service API URL. If empty, the service's root URL will be used.")
	headerPath     = flag.String("header_path", "", "If non-empty, prepend the contents of this file to generated services.")

	gensupportPkg = flag.String("gensupport_pkg", "google.golang.org/api/gensupport", "Go package path of the 'api/gensupport' support package.")
	googleapiPkg  = flag.String("googleapi_pkg", "google.golang.org/api/googleapi", "Go package path of the 'api/googleapi' support package.")

	serviceTypes = []string{"Service", "APIService"}
)

// API represents an API to generate, as well as its state while it's
// generating.
type API struct {
	// Fields needed before generating code, to select and find the APIs
	// to generate.
	// These fields usually come from the "directory item" JSON objects
	// that are provided by the googleDiscoveryURL. We unmarshal a directory
	// item directly into this struct.
	ID            string `json:"id"`
	Name          string `json:"name"`
	Version       string `json:"version"`
	DiscoveryLink string `json:"discoveryRestUrl"` // absolute

	doc *disco.Document
	// TODO(jba): remove m when we've fully converted to using disco.
	m map[string]interface{}

	forceJSON     []byte // if non-nil, the JSON schema file. else fetched.
	usedNames     namePool
	schemas       map[string]*Schema // apiName -> schema
	responseTypes map[string]bool

	p  func(format string, args ...interface{}) // print raw
	pn func(format string, args ...interface{}) // print with newline
}

func (a *API) sortedSchemaNames() (names []string) {
	for name := range a.schemas {
		names = append(names, name)
	}
	sort.Strings(names)
	return
}

func (a *API) Schema(name string) *Schema {
	return a.schemas[name]
}

type generateError struct {
	api   *API
	error error
}

func (e *generateError) Error() string {
	return fmt.Sprintf("API %s failed to generate code: %v", e.api.ID, e.error)
}

type compileError struct {
	api    *API
	output string
}

func (e *compileError) Error() string {
	return fmt.Sprintf("API %s failed to compile:\n%v", e.api.ID, e.output)
}

func main() {
	flag.Parse()

	if *install {
		*build = true
	}

	var (
		apiIds  = []string{}
		matches = []*API{}
		errors  = []error{}
	)
	for _, api := range getAPIs() {
		apiIds = append(apiIds, api.ID)
		if !api.want() {
			continue
		}
		matches = append(matches, api)
		log.Printf("Generating API %s", api.ID)
		err := api.WriteGeneratedCode()
		if err != nil && err != errNoDoc {
			errors = append(errors, &generateError{api, err})
			continue
		}
		if *build && err == nil {
			var args []string
			if *install {
				args = append(args, "install")
			} else {
				args = append(args, "build")
			}
			args = append(args, api.Target())
			out, err := exec.Command("go", args...).CombinedOutput()
			if err != nil {
				errors = append(errors, &compileError{api, string(out)})
			}
		}
	}

	if len(matches) == 0 {
		log.Fatalf("No APIs matched %q; options are %v", *apiToGenerate, apiIds)
	}

	if len(errors) > 0 {
		log.Printf("%d API(s) failed to generate or compile:", len(errors))
		for _, ce := range errors {
			log.Println(ce.Error())
		}
		os.Exit(1)
	}
}

func (a *API) want() bool {
	if *jsonFile != "" {
		// Return true early, before calling a.JSONFile()
		// which will require a GOPATH be set.  This is for
		// integration with Google's build system genrules
		// where there is no GOPATH.
		return true
	}
	// Skip this API if we're in cached mode and the files don't exist on disk.
	if *useCache {
		if _, err := os.Stat(a.JSONFile()); os.IsNotExist(err) {
			return false
		}
	}
	return *apiToGenerate == "*" || *apiToGenerate == a.ID
}

func getAPIs() []*API {
	if *jsonFile != "" {
		return getAPIsFromFile()
	}
	var bytes []byte
	var source string
	apiListFile := filepath.Join(genDirRoot(), "api-list.json")
	if *useCache {
		if !*publicOnly {
			log.Fatalf("-cache=true not compatible with -publiconly=false")
		}
		var err error
		bytes, err = ioutil.ReadFile(apiListFile)
		if err != nil {
			log.Fatal(err)
		}
		source = apiListFile
	} else {
		bytes = slurpURL(*apisURL)
		if *publicOnly {
			if err := writeFile(apiListFile, bytes); err != nil {
				log.Fatal(err)
			}
		}
		source = *apisURL
	}
	apis, err := unmarshalAPIs(bytes)
	if err != nil {
		log.Fatalf("error decoding JSON in %s: %v", source, err)
	}
	if !*publicOnly && *apiToGenerate != "*" {
		apis = append(apis, apiFromID(*apiToGenerate))
	}
	return apis
}

func unmarshalAPIs(bytes []byte) ([]*API, error) {
	var itemObj struct{ Items []*API }
	if err := json.Unmarshal(bytes, &itemObj); err != nil {
		return nil, err
	}
	return itemObj.Items, nil
}

func apiFromID(apiID string) *API {
	parts := strings.Split(apiID, ":")
	if len(parts) != 2 {
		log.Fatalf("malformed API name: %q", apiID)
	}
	return &API{
		ID:      apiID,
		Name:    parts[0],
		Version: parts[1],
	}
}

// getAPIsFromFile handles the case of generating exactly one API
// from the flag given in --api_json_file
func getAPIsFromFile() []*API {
	if *apiToGenerate != "*" {
		log.Fatalf("Can't set --api with --api_json_file.")
	}
	if !*publicOnly {
		log.Fatalf("Can't set --publiconly with --api_json_file.")
	}
	a, err := apiFromFile(*jsonFile)
	if err != nil {
		log.Fatal(err)
	}
	return []*API{a}
}

func apiFromFile(file string) (*API, error) {
	jsonBytes, err := ioutil.ReadFile(file)
	if err != nil {
		return nil, fmt.Errorf("Error reading %s: %v", file, err)
	}
	doc, err := disco.NewDocument(jsonBytes)
	if err != nil {
		return nil, fmt.Errorf("reading document from %q: %v", file, err)
	}
	a := &API{
		ID:        doc.ID,
		Name:      doc.Name,
		Version:   doc.Version,
		forceJSON: jsonBytes,
		doc:       doc,
	}
	return a, nil
}

func writeFile(file string, contents []byte) error {
	// Don't write it if the contents are identical.
	existing, err := ioutil.ReadFile(file)
	if err == nil && (bytes.Equal(existing, contents) || basicallyEqual(existing, contents)) {
		return nil
	}
	outdir := filepath.Dir(file)
	if err = os.MkdirAll(outdir, 0755); err != nil {
		return fmt.Errorf("failed to Mkdir %s: %v", outdir, err)
	}
	return ioutil.WriteFile(file, contents, 0644)
}

var ignoreLines = regexp.MustCompile(`(?m)^\s+"(?:etag|revision)": ".+\n`)

// basicallyEqual reports whether a and b are equal except for boring
// differences like ETag updates.
func basicallyEqual(a, b []byte) bool {
	return ignoreLines.Match(a) && ignoreLines.Match(b) &&
		bytes.Equal(ignoreLines.ReplaceAll(a, nil), ignoreLines.ReplaceAll(b, nil))
}

func slurpURL(urlStr string) []byte {
	if *useCache {
		log.Fatalf("Invalid use of slurpURL in cached mode for URL %s", urlStr)
	}
	req, err := http.NewRequest("GET", urlStr, nil)
	if err != nil {
		log.Fatal(err)
	}
	if *publicOnly {
		req.Header.Add("X-User-IP", "0.0.0.0") // hack
	}
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatalf("Error fetching URL %s: %v", urlStr, err)
	}
	if res.StatusCode >= 300 {
		log.Printf("WARNING: URL %s served status code %d", urlStr, res.StatusCode)
		return nil
	}
	bs, err := ioutil.ReadAll(res.Body)
	if err != nil {
		log.Fatalf("Error reading body of URL %s: %v", urlStr, err)
	}
	return bs
}

func panicf(format string, args ...interface{}) {
	panic(fmt.Sprintf(format, args...))
}

// namePool keeps track of used names and assigns free ones based on a
// preferred name
type namePool struct {
	m map[string]bool // lazily initialized
}

// oddVersionRE matches unusual API names like directory_v1.
var oddVersionRE = regexp.MustCompile(`^(.+)_(v[\d\.]+)$`)

// renameVersion conditionally rewrites the provided version such
// that the final path component of the import path doesn't look
// like a Go identifier. This keeps the consistency that import paths
// for the generated Go packages look like:
//     google.golang.org/api/NAME/v<version>
// and have package NAME.
// See https://github.com/google/google-api-go-client/issues/78
func renameVersion(version string) string {
	if version == "alpha" || version == "beta" {
		return "v0." + version
	}
	if m := oddVersionRE.FindStringSubmatch(version); m != nil {
		return m[1] + "/" + m[2]
	}
	return version
}

func (p *namePool) Get(preferred string) string {
	if p.m == nil {
		p.m = make(map[string]bool)
	}
	name := preferred
	tries := 0
	for p.m[name] {
		tries++
		name = fmt.Sprintf("%s%d", preferred, tries)
	}
	p.m[name] = true
	return name
}

func genDirRoot() string {
	if *genDir != "" {
		return *genDir
	}
	paths := filepath.SplitList(os.Getenv("GOPATH"))
	if len(paths) == 0 {
		log.Fatalf("No GOPATH set.")
	}
	return filepath.Join(paths[0], "src", "google.golang.org", "api")
}

func (a *API) SourceDir() string {
	return filepath.Join(genDirRoot(), a.Package(), renameVersion(a.Version))
}

func (a *API) DiscoveryURL() string {
	if a.DiscoveryLink == "" {
		log.Fatalf("API %s has no DiscoveryLink", a.ID)
	}
	return a.DiscoveryLink
}

func (a *API) Package() string {
	return strings.ToLower(a.Name)
}

func (a *API) Target() string {
	return fmt.Sprintf("%s/%s/%s", *apiPackageBase, a.Package(), renameVersion(a.Version))
}

// ServiceType returns the name of the type to use for the root API struct
// (typically "Service").
func (a *API) ServiceType() string {
	switch a.Name {
	case "appengine", "content": // retained for historical compatibility.
		return "APIService"
	default:
		for _, t := range serviceTypes {
			if _, ok := a.schemas[t]; !ok {
				return t
			}
		}
		panic("all service types are used, please consider introducing a new type to serviceTypes.")
	}
}

// GetName returns a free top-level function/type identifier in the package.
// It tries to return your preferred match if it's free.
func (a *API) GetName(preferred string) string {
	return a.usedNames.Get(preferred)
}

func (a *API) apiBaseURL() string {
	var base, rel string
	switch {
	case *baseURL != "":
		base, rel = *baseURL, a.doc.BasePath
	case a.doc.RootURL != "":
		base, rel = a.doc.RootURL, a.doc.ServicePath
	default:
		base, rel = *apisURL, a.doc.BasePath
	}
	return resolveRelative(base, rel)
}

func (a *API) needsDataWrapper() bool {
	for _, feature := range a.doc.Features {
		if feature == "dataWrapper" {
			return true
		}
	}
	return false
}

func (a *API) jsonBytes() []byte {
	if a.forceJSON == nil {
		var slurp []byte
		var err error
		if *useCache {
			slurp, err = ioutil.ReadFile(a.JSONFile())
			if err != nil {
				log.Fatal(err)
			}
		} else {
			slurp = slurpURL(a.DiscoveryURL())
			if slurp != nil {
				// Make sure that keys are sorted by re-marshalling.
				d := make(map[string]interface{})
				json.Unmarshal(slurp, &d)
				if err != nil {
					log.Fatal(err)
				}
				var err error
				slurp, err = json.MarshalIndent(d, "", "  ")
				if err != nil {
					log.Fatal(err)
				}
			}
		}
		a.forceJSON = slurp
	}
	return a.forceJSON
}

func (a *API) JSONFile() string {
	return filepath.Join(a.SourceDir(), a.Package()+"-api.json")
}

var errNoDoc = errors.New("could not read discovery doc")

// WriteGeneratedCode generates code for a.
// It returns errNoDoc if we couldn't read the discovery doc.
func (a *API) WriteGeneratedCode() error {
	genfilename := *output
	jsonBytes := a.jsonBytes()
	// Skip generation if we don't have the discovery doc.
	if jsonBytes == nil {
		// No message here, because slurpURL printed one.
		return errNoDoc
	}
	if genfilename == "" {
		if err := writeFile(a.JSONFile(), jsonBytes); err != nil {
			return err
		}
		outdir := a.SourceDir()
		err := os.MkdirAll(outdir, 0755)
		if err != nil {
			return fmt.Errorf("failed to Mkdir %s: %v", outdir, err)
		}
		pkg := a.Package()
		genfilename = filepath.Join(outdir, pkg+"-gen.go")
	}

	code, err := a.GenerateCode()
	errw := writeFile(genfilename, code)
	if err == nil {
		err = errw
	}
	if err != nil {
		return err
	}
	return nil
}

var docsLink string

func (a *API) GenerateCode() ([]byte, error) {
	pkg := a.Package()

	jsonBytes := a.jsonBytes()
	var err error
	if a.doc == nil {
		a.doc, err = disco.NewDocument(jsonBytes)
		if err != nil {
			return nil, err
		}
	}

	// Buffer the output in memory, for gofmt'ing later.
	var buf bytes.Buffer
	a.p = func(format string, args ...interface{}) {
		_, err := fmt.Fprintf(&buf, format, args...)
		if err != nil {
			panic(err)
		}
	}
	a.pn = func(format string, args ...interface{}) {
		a.p(format+"\n", args...)
	}
	wf := func(path string) error {
		f, err := os.Open(path)
		if err != nil {
			return err
		}
		defer f.Close()

		_, err = io.Copy(&buf, f)
		return err
	}

	p, pn := a.p, a.pn

	if *headerPath != "" {
		if err := wf(*headerPath); err != nil {
			return nil, err
		}
	}

	pn(fmt.Sprintf(`// Copyright %d Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.
`, time.Now().Year()))

	pn("// Package %s provides access to the %s.", pkg, a.doc.Title)
	if r := replacementPackage[pkg]; r != "" {
		pn("//")
		pn("// This package is DEPRECATED. Use package %s instead.", r)
	}
	docsLink = a.doc.DocumentationLink
	if docsLink != "" {
		pn("//")
		pn("// See %s", docsLink)
	}
	pn("//\n// Usage example:")
	pn("//")
	pn("//   import %q", a.Target())
	pn("//   ...")
	pn("//   %sService, err := %s.New(oauthHttpClient)", pkg, pkg)

	pn("package %s // import %q", pkg, a.Target())
	p("\n")
	pn("import (")
	for _, imp := range []string{
		"bytes",
		"context",
		"encoding/json",
		"errors",
		"fmt",
		"io",
		"net/http",
		"net/url",
		"strconv",
		"strings",
	} {
		pn("  %q", imp)
	}
	pn("")
	for _, imp := range []struct {
		pkg   string
		lname string
	}{
		{*gensupportPkg, "gensupport"},
		{*googleapiPkg, "googleapi"},
	} {
		pn("  %s %q", imp.lname, imp.pkg)
	}
	pn(")")
	pn("\n// Always reference these packages, just in case the auto-generated code")
	pn("// below doesn't.")
	pn("var _ = bytes.NewBuffer")
	pn("var _ = strconv.Itoa")
	pn("var _ = fmt.Sprintf")
	pn("var _ = json.NewDecoder")
	pn("var _ = io.Copy")
	pn("var _ = url.Parse")
	pn("var _ = gensupport.MarshalJSON")
	pn("var _ = googleapi.Version")
	pn("var _ = errors.New")
	pn("var _ = strings.Replace")
	pn("var _ = context.Canceled")
	pn("")
	pn("const apiId = %q", a.doc.ID)
	pn("const apiName = %q", a.doc.Name)
	pn("const apiVersion = %q", a.doc.Version)
	pn("const basePath = %q", a.apiBaseURL())

	a.generateScopeConstants()
	a.PopulateSchemas()

	service := a.ServiceType()

	// Reserve names (ignore return value; we're the first caller).
	a.GetName("New")
	a.GetName(service)

	pn("func New(client *http.Client) (*%s, error) {", service)
	pn("if client == nil { return nil, errors.New(\"client is nil\") }")
	pn("s := &%s{client: client, BasePath: basePath}", service)
	for _, res := range a.doc.Resources { // add top level resources.
		pn("s.%s = New%s(s)", resourceGoField(res, nil), resourceGoType(res))
	}
	pn("return s, nil")
	pn("}")

	pn("\ntype %s struct {", service)
	pn(" client *http.Client")
	pn(" BasePath string // API endpoint base URL")
	pn(" UserAgent string // optional additional User-Agent fragment")

	for _, res := range a.doc.Resources {
		pn("\n\t%s\t*%s", resourceGoField(res, nil), resourceGoType(res))
	}
	pn("}")
	pn("\nfunc (s *%s) userAgent() string {", service)
	pn(` if s.UserAgent == "" { return googleapi.UserAgent }`)
	pn(` return googleapi.UserAgent + " " + s.UserAgent`)
	pn("}\n")

	for _, res := range a.doc.Resources {
		a.generateResource(res)
	}

	a.responseTypes = make(map[string]bool)
	for _, meth := range a.APIMethods() {
		meth.cacheResponseTypes(a)
	}
	for _, res := range a.doc.Resources {
		a.cacheResourceResponseTypes(res)
	}

	for _, name := range a.sortedSchemaNames() {
		a.schemas[name].writeSchemaCode(a)
	}

	for _, meth := range a.APIMethods() {
		meth.generateCode()
	}

	for _, res := range a.doc.Resources {
		a.generateResourceMethods(res)
	}

	clean, err := format.Source(buf.Bytes())
	if err != nil {
		return buf.Bytes(), err
	}
	return clean, nil
}

func (a *API) generateScopeConstants() {
	scopes := a.doc.Auth.OAuth2Scopes
	if len(scopes) == 0 {
		return
	}

	a.pn("// OAuth2 scopes used by this API.")
	a.pn("const (")
	n := 0
	for _, scope := range scopes {
		if n > 0 {
			a.p("\n")
		}
		n++
		ident := scopeIdentifierFromURL(scope.URL)
		if scope.Description != "" {
			a.p("%s", asComment("\t", scope.Description))
		}
		a.pn("\t%s = %q", ident, scope.URL)
	}
	a.p(")\n\n")
}

func scopeIdentifierFromURL(urlStr string) string {
	const prefix = "https://www.googleapis.com/auth/"
	if !strings.HasPrefix(urlStr, prefix) {
		const https = "https://"
		if !strings.HasPrefix(urlStr, https) {
			log.Fatalf("Unexpected oauth2 scope %q doesn't start with %q", urlStr, https)
		}
		ident := validGoIdentifer(depunct(urlStr[len(https):], true)) + "Scope"
		return ident
	}
	ident := validGoIdentifer(initialCap(urlStr[len(prefix):])) + "Scope"
	return ident
}

// Schema is a disco.Schema that has been bestowed an identifier, whether by
// having an "id" field at the top of the schema or with an
// automatically generated one in populateSubSchemas.
//
// TODO: While sub-types shouldn't need to be promoted to schemas,
// API.GenerateCode iterates over API.schemas to figure out what
// top-level Go types to write.  These should be separate concerns.
type Schema struct {
	api *API

	typ *disco.Schema

	apiName      string // the native API-defined name of this type
	goName       string // lazily populated by GoName
	goReturnType string // lazily populated by GoReturnType
	props        []*Property
}

type Property struct {
	s              *Schema // the containing Schema
	p              *disco.Property
	assignedGoName string
}

func (p *Property) Type() *disco.Schema {
	return p.p.Schema
}

func (p *Property) GoName() string {
	return initialCap(p.p.Name)
}

func (p *Property) Default() string {
	return p.p.Schema.Default
}

func (p *Property) Description() string {
	return p.p.Schema.Description
}

func (p *Property) Enum() ([]string, bool) {
	typ := p.p.Schema
	if typ.Enums != nil {
		return typ.Enums, true
	}
	// Check if this has an array of string enums.
	if typ.ItemSchema != nil {
		if enums := typ.ItemSchema.Enums; enums != nil && typ.ItemSchema.Type == "string" {
			return enums, true
		}
	}
	return nil, false
}

func (p *Property) EnumDescriptions() []string {
	if desc := p.p.Schema.EnumDescriptions; desc != nil {
		return desc
	}
	// Check if this has an array of string enum descriptions.
	if items := p.p.Schema.ItemSchema; items != nil {
		if desc := items.EnumDescriptions; desc != nil {
			return desc
		}
	}
	return nil
}

func (p *Property) Pattern() (string, bool) {
	return p.p.Schema.Pattern, (p.p.Schema.Pattern != "")
}

func (p *Property) TypeAsGo() string {
	return p.s.api.typeAsGo(p.Type(), false)
}

// A FieldName uniquely identifies a field within a Schema struct for an API.
type fieldName struct {
	api    string // The ID of an API.
	schema string // The Go name of a Schema struct.
	field  string // The Go name of a field.
}

// pointerFields is a list of fields that should use a pointer type.
// This makes it possible to distinguish between a field being unset vs having
// an empty value.
var pointerFields = []fieldName{
	{api: "androidpublisher:v1.1", schema: "InappPurchase", field: "PurchaseType"},
	{api: "androidpublisher:v2", schema: "ProductPurchase", field: "PurchaseType"},
	{api: "androidpublisher:v3", schema: "ProductPurchase", field: "PurchaseType"},
	{api: "androidpublisher:v2", schema: "SubscriptionPurchase", field: "CancelReason"},
	{api: "androidpublisher:v2", schema: "SubscriptionPurchase", field: "PaymentState"},
	{api: "androidpublisher:v2", schema: "SubscriptionPurchase", field: "PurchaseType"},
	{api: "androidpublisher:v3", schema: "SubscriptionPurchase", field: "PurchaseType"},
	{api: "cloudmonitoring:v2beta2", schema: "Point", field: "BoolValue"},
	{api: "cloudmonitoring:v2beta2", schema: "Point", field: "DoubleValue"},
	{api: "cloudmonitoring:v2beta2", schema: "Point", field: "Int64Value"},
	{api: "cloudmonitoring:v2beta2", schema: "Point", field: "StringValue"},
	{api: "compute:alpha", schema: "Scheduling", field: "AutomaticRestart"},
	{api: "compute:beta", schema: "MetadataItems", field: "Value"},
	{api: "compute:beta", schema: "Scheduling", field: "AutomaticRestart"},
	{api: "compute:v1", schema: "MetadataItems", field: "Value"},
	{api: "compute:v1", schema: "Scheduling", field: "AutomaticRestart"},
	{api: "content:v2", schema: "AccountUser", field: "Admin"},
	{api: "datastore:v1beta2", schema: "Property", field: "BlobKeyValue"},
	{api: "datastore:v1beta2", schema: "Property", field: "BlobValue"},
	{api: "datastore:v1beta2", schema: "Property", field: "BooleanValue"},
	{api: "datastore:v1beta2", schema: "Property", field: "DateTimeValue"},
	{api: "datastore:v1beta2", schema: "Property", field: "DoubleValue"},
	{api: "datastore:v1beta2", schema: "Property", field: "Indexed"},
	{api: "datastore:v1beta2", schema: "Property", field: "IntegerValue"},
	{api: "datastore:v1beta2", schema: "Property", field: "StringValue"},
	{api: "datastore:v1beta3", schema: "Value", field: "BlobValue"},
	{api: "datastore:v1beta3", schema: "Value", field: "BooleanValue"},
	{api: "datastore:v1beta3", schema: "Value", field: "DoubleValue"},
	{api: "datastore:v1beta3", schema: "Value", field: "IntegerValue"},
	{api: "datastore:v1beta3", schema: "Value", field: "StringValue"},
	{api: "datastore:v1beta3", schema: "Value", field: "TimestampValue"},
	{api: "genomics:v1beta2", schema: "Dataset", field: "IsPublic"},
	{api: "monitoring:v3", schema: "TypedValue", field: "BoolValue"},
	{api: "monitoring:v3", schema: "TypedValue", field: "DoubleValue"},
	{api: "monitoring:v3", schema: "TypedValue", field: "Int64Value"},
	{api: "monitoring:v3", schema: "TypedValue", field: "StringValue"},
	{api: "servicecontrol:v1", schema: "MetricValue", field: "BoolValue"},
	{api: "servicecontrol:v1", schema: "MetricValue", field: "DoubleValue"},
	{api: "servicecontrol:v1", schema: "MetricValue", field: "Int64Value"},
	{api: "servicecontrol:v1", schema: "MetricValue", field: "StringValue"},
	{api: "sqladmin:v1beta4", schema: "Settings", field: "StorageAutoResize"},
	{api: "storage:v1", schema: "BucketLifecycleRuleCondition", field: "IsLive"},
	{api: "storage:v1beta2", schema: "BucketLifecycleRuleCondition", field: "IsLive"},
	{api: "tasks:v1", schema: "Task", field: "Completed"},
	{api: "youtube:v3", schema: "ChannelSectionSnippet", field: "Position"},
}

// forcePointerType reports whether p should be represented as a pointer type in its parent schema struct.
func (p *Property) forcePointerType() bool {
	if p.UnfortunateDefault() {
		return true
	}

	name := fieldName{api: p.s.api.ID, schema: p.s.GoName(), field: p.GoName()}
	for _, pf := range pointerFields {
		if pf == name {
			return true
		}
	}
	return false
}

// UnfortunateDefault reports whether p may be set to a zero value, but has a non-zero default.
func (p *Property) UnfortunateDefault() bool {
	switch p.TypeAsGo() {
	default:
		return false

	case "bool":
		return p.Default() == "true"

	case "string":
		if p.Default() == "" {
			return false
		}
		// String fields are considered to "allow" a zero value if either:
		//  (a) they are an enum, and one of the permitted enum values is the empty string, or
		//  (b) they have a validation pattern which matches the empty string.
		pattern, hasPat := p.Pattern()
		enum, hasEnum := p.Enum()
		if hasPat && hasEnum {
			log.Printf("Encountered enum property which also has a pattern: %#v", p)
			return false // don't know how to handle this, so ignore.
		}
		return (hasPat && emptyPattern(pattern)) ||
			(hasEnum && emptyEnum(enum))

	case "float64", "int64", "uint64", "int32", "uint32":
		if p.Default() == "" {
			return false
		}
		if f, err := strconv.ParseFloat(p.Default(), 64); err == nil {
			return f != 0.0
		}
		// The default value has an unexpected form.  Whatever it is, it's non-zero.
		return true
	}
}

// emptyPattern reports whether a pattern matches the empty string.
func emptyPattern(pattern string) bool {
	if re, err := regexp.Compile(pattern); err == nil {
		return re.MatchString("")
	}
	log.Printf("Encountered bad pattern: %s", pattern)
	return false
}

// emptyEnum reports whether a property enum list contains the empty string.
func emptyEnum(enum []string) bool {
	for _, val := range enum {
		if val == "" {
			return true
		}
	}
	return false
}

func (a *API) typeAsGo(s *disco.Schema, elidePointers bool) string {
	switch s.Kind {
	case disco.SimpleKind:
		return mustSimpleTypeConvert(s.Type, s.Format)
	case disco.ArrayKind:
		as := s.ElementSchema()
		if as.Type == "string" {
			switch as.Format {
			case "int64":
				return "googleapi.Int64s"
			case "uint64":
				return "googleapi.Uint64s"
			case "int32":
				return "googleapi.Int32s"
			case "uint32":
				return "googleapi.Uint32s"
			case "float64":
				return "googleapi.Float64s"
			}
		}
		return "[]" + a.typeAsGo(as, elidePointers)
	case disco.ReferenceKind:
		rs := s.RefSchema
		if rs.Kind == disco.SimpleKind {
			// Simple top-level schemas get named types (see writeSchemaCode).
			// Use the name instead of using the equivalent simple Go type.
			return a.schemaNamed(rs.Name).GoName()
		}
		return a.typeAsGo(rs, elidePointers)
	case disco.MapKind:
		es := s.ElementSchema()
		if es.Type == "string" {
			// If the element schema has a type "string", it's going to be
			// transmitted as a string, and the Go map type must reflect that.
			// This is true even if the format is, say, "int64". When type =
			// "string" and format = "int64" at top level, we can use the json
			// "string" tag option to unmarshal the string to an int64, but
			// inside a map we can't.
			return "map[string]string"
		}
		// Due to historical baggage (maps used to be a separate code path),
		// the element types of maps never have pointers in them.  From this
		// level down, elide pointers in types.
		return "map[string]" + a.typeAsGo(es, true)
	case disco.AnyStructKind:
		return "googleapi.RawMessage"
	case disco.StructKind:
		tls := a.schemaNamed(s.Name)
		if elidePointers || s.Variant != nil {
			return tls.GoName()
		}
		return "*" + tls.GoName()
	default:
		panic(fmt.Sprintf("unhandled typeAsGo for %+v", s))
	}
}

func (a *API) schemaNamed(name string) *Schema {
	s := a.schemas[name]
	if s == nil {
		panicf("no top-level schema named %q", name)
	}
	return s
}

func (s *Schema) properties() []*Property {
	if s.props != nil {
		return s.props
	}
	if s.typ.Kind != disco.StructKind {
		panic("called properties on non-object schema")
	}
	for _, p := range s.typ.Properties {
		s.props = append(s.props, &Property{
			s: s,
			p: p,
		})
	}
	return s.props
}

func (s *Schema) HasContentType() bool {
	for _, p := range s.properties() {
		if p.GoName() == "ContentType" && p.TypeAsGo() == "string" {
			return true
		}
	}
	return false
}

func (s *Schema) populateSubSchemas() (outerr error) {
	defer func() {
		r := recover()
		if r == nil {
			return
		}
		outerr = fmt.Errorf("%v", r)
	}()

	addSubStruct := func(subApiName string, t *disco.Schema) {
		if s.api.schemas[subApiName] != nil {
			panic("dup schema apiName: " + subApiName)
		}
		if t.Name != "" {
			panic("subtype already has name: " + t.Name)
		}
		t.Name = subApiName
		subs := &Schema{
			api:     s.api,
			typ:     t,
			apiName: subApiName,
		}
		s.api.schemas[subApiName] = subs
		err := subs.populateSubSchemas()
		if err != nil {
			panicf("in sub-struct %q: %v", subApiName, err)
		}
	}

	switch s.typ.Kind {
	case disco.StructKind:
		for _, p := range s.properties() {
			subApiName := fmt.Sprintf("%s.%s", s.apiName, p.p.Name)
			switch p.Type().Kind {
			case disco.SimpleKind, disco.ReferenceKind, disco.AnyStructKind:
				// Do nothing.
			case disco.MapKind:
				mt := p.Type().ElementSchema()
				if mt.Kind == disco.SimpleKind || mt.Kind == disco.ReferenceKind {
					continue
				}
				addSubStruct(subApiName, mt)
			case disco.ArrayKind:
				at := p.Type().ElementSchema()
				if at.Kind == disco.SimpleKind || at.Kind == disco.ReferenceKind {
					continue
				}
				addSubStruct(subApiName, at)
			case disco.StructKind:
				addSubStruct(subApiName, p.Type())
			default:
				panicf("Unknown type for %q: %v", subApiName, p.Type())
			}
		}
	case disco.ArrayKind:
		subApiName := fmt.Sprintf("%s.Item", s.apiName)
		switch at := s.typ.ElementSchema(); at.Kind {
		case disco.SimpleKind, disco.ReferenceKind, disco.AnyStructKind:
			// Do nothing.
		case disco.MapKind:
			mt := at.ElementSchema()
			if k := mt.Kind; k != disco.SimpleKind && k != disco.ReferenceKind {
				addSubStruct(subApiName, mt)
			}
		case disco.ArrayKind:
			at := at.ElementSchema()
			if k := at.Kind; k != disco.SimpleKind && k != disco.ReferenceKind {
				addSubStruct(subApiName, at)
			}
		case disco.StructKind:
			addSubStruct(subApiName, at)
		default:
			panicf("Unknown array type for %q: %v", subApiName, at)
		}
	case disco.AnyStructKind, disco.MapKind, disco.SimpleKind, disco.ReferenceKind:
		// Do nothing.
	default:
		fmt.Fprintf(os.Stderr, "in populateSubSchemas, schema is: %v", s.typ)
		panicf("populateSubSchemas: unsupported type for schema %q", s.apiName)
		panic("unreachable")
	}
	return nil
}

// GoName returns (or creates and returns) the bare Go name
// of the apiName, making sure that it's a proper Go identifier
// and doesn't conflict with an existing name.
func (s *Schema) GoName() string {
	if s.goName == "" {
		if s.typ.Kind == disco.MapKind {
			s.goName = s.api.typeAsGo(s.typ, false)
		} else {
			base := initialCap(s.apiName)
			s.goName = s.api.GetName(base)
			if base == "Service" && s.goName != "Service" {
				// Detect the case where a resource is going to clash with the
				// root service object.
				panicf("Clash on name Service")
			}
		}
	}
	return s.goName
}

// GoReturnType returns the Go type to use as the return type.
// If a type is a struct, it will return *StructType,
// for a map it will return map[string]ValueType,
// for (not yet supported) slices it will return []ValueType.
func (s *Schema) GoReturnType() string {
	if s.goReturnType == "" {
		if s.typ.Kind == disco.MapKind {
			s.goReturnType = s.GoName()
		} else {
			s.goReturnType = "*" + s.GoName()
		}
	}
	return s.goReturnType
}

func (s *Schema) writeSchemaCode(api *API) {
	switch s.typ.Kind {
	case disco.SimpleKind:
		apitype := s.typ.Type
		typ := mustSimpleTypeConvert(apitype, s.typ.Format)
		s.api.pn("\ntype %s %s", s.GoName(), typ)
	case disco.StructKind:
		s.writeSchemaStruct(api)
	case disco.MapKind, disco.AnyStructKind:
		// Do nothing.
	case disco.ArrayKind:
		log.Printf("TODO writeSchemaCode for arrays for %s", s.GoName())
	default:
		fmt.Fprintf(os.Stderr, "in writeSchemaCode, schema is: %+v", s.typ)
		panicf("writeSchemaCode: unsupported type for schema %q", s.apiName)
	}
}

func (s *Schema) writeVariant(api *API, v *disco.Variant) {
	s.api.p("\ntype %s map[string]interface{}\n\n", s.GoName())

	// Write out the "Type" method that identifies the variant type.
	s.api.pn("func (t %s) Type() string {", s.GoName())
	s.api.pn("  return googleapi.VariantType(t)")
	s.api.p("}\n\n")

	// Write out helper methods to convert each possible variant.
	for _, m := range v.Map {
		if m.TypeValue == "" && m.Ref == "" {
			log.Printf("TODO variant %s ref %s not yet supported.", m.TypeValue, m.Ref)
			continue
		}

		s.api.pn("func (t %s) %s() (r %s, ok bool) {", s.GoName(), initialCap(m.TypeValue), m.Ref)
		s.api.pn(" if t.Type() != %q {", initialCap(m.TypeValue))
		s.api.pn("  return r, false")
		s.api.pn(" }")
		s.api.pn(" ok = googleapi.ConvertVariant(map[string]interface{}(t), &r)")
		s.api.pn(" return r, ok")
		s.api.p("}\n\n")
	}
}

func (s *Schema) Description() string {
	return s.typ.Description
}

func (s *Schema) writeSchemaStruct(api *API) {
	if v := s.typ.Variant; v != nil {
		s.writeVariant(api, v)
		return
	}
	s.api.p("\n")
	des := s.Description()
	if des != "" {
		s.api.p("%s", asComment("", fmt.Sprintf("%s: %s", s.GoName(), des)))
	}
	s.api.pn("type %s struct {", s.GoName())

	np := new(namePool)
	forceSendName := np.Get("ForceSendFields")
	nullFieldsName := np.Get("NullFields")
	if s.isResponseType() {
		np.Get("ServerResponse") // reserve the name
	}

	firstFieldName := "" // used to store a struct field name for use in documentation.
	for i, p := range s.properties() {
		if i > 0 {
			s.api.p("\n")
		}
		pname := np.Get(p.GoName())
		if pname[0] == '@' {
			// HACK(cbro): ignore JSON-LD special fields until we can figure out
			// the correct Go representation for them.
			continue
		}
		p.assignedGoName = pname
		des := p.Description()
		if des != "" {
			s.api.p("%s", asComment("\t", fmt.Sprintf("%s: %s", pname, des)))
		}
		addFieldValueComments(s.api.p, p, "\t", des != "")

		var extraOpt string
		if p.Type().IsIntAsString() {
			extraOpt += ",string"
		}

		typ := p.TypeAsGo()
		if p.forcePointerType() {
			typ = "*" + typ
		}

		s.api.pn(" %s %s `json:\"%s,omitempty%s\"`", pname, typ, p.p.Name, extraOpt)
		if firstFieldName == "" {
			firstFieldName = pname
		}
	}

	if s.isResponseType() {
		if firstFieldName != "" {
			s.api.p("\n")
		}
		s.api.p("%s", asComment("\t", "ServerResponse contains the HTTP response code and headers from the server."))
		s.api.pn(" googleapi.ServerResponse `json:\"-\"`")
	}

	if firstFieldName == "" {
		// There were no fields in the struct, so there is no point
		// adding any custom JSON marshaling code.
		s.api.pn("}")
		return
	}

	commentFmtStr := "%s is a list of field names (e.g. %q) to " +
		"unconditionally include in API requests. By default, fields " +
		"with empty values are omitted from API requests. However, " +
		"any non-pointer, non-interface field appearing in %s will " +
		"be sent to the server regardless of whether the field is " +
		"empty or not. This may be used to include empty fields in " +
		"Patch requests."
	comment := fmt.Sprintf(commentFmtStr, forceSendName, firstFieldName, forceSendName)
	s.api.p("\n")
	s.api.p("%s", asComment("\t", comment))

	s.api.pn("\t%s []string `json:\"-\"`", forceSendName)

	commentFmtStr = "%s is a list of field names (e.g. %q) to " +
		"include in API requests with the JSON null value. " +
		"By default, fields with empty values are omitted from API requests. However, " +
		"any field with an empty value appearing in %s will be sent to the server as null. " +
		"It is an error if a field in this list has a non-empty value. This may be used to " +
		"include null fields in Patch requests."
	comment = fmt.Sprintf(commentFmtStr, nullFieldsName, firstFieldName, nullFieldsName)
	s.api.p("\n")
	s.api.p("%s", asComment("\t", comment))

	s.api.pn("\t%s []string `json:\"-\"`", nullFieldsName)

	s.api.pn("}")
	s.writeSchemaMarshal(forceSendName, nullFieldsName)
	s.writeSchemaUnmarshal()
}

// writeSchemaMarshal writes a custom MarshalJSON function for s, which allows
// fields to be explicitly transmitted by listing them in the field identified
// by forceSendFieldName, and allows fields to be transmitted with the null value
// by listing them in the field identified by nullFieldsName.
func (s *Schema) writeSchemaMarshal(forceSendFieldName, nullFieldsName string) {
	s.api.pn("func (s *%s) MarshalJSON() ([]byte, error) {", s.GoName())
	s.api.pn("\ttype NoMethod %s", s.GoName())
	// pass schema as methodless type to prevent subsequent calls to MarshalJSON from recursing indefinitely.
	s.api.pn("\traw := NoMethod(*s)")
	s.api.pn("\treturn gensupport.MarshalJSON(raw, s.%s, s.%s)", forceSendFieldName, nullFieldsName)
	s.api.pn("}")
}

func (s *Schema) writeSchemaUnmarshal() {
	var floatProps []*Property
	for _, p := range s.properties() {
		if p.p.Schema.Type == "number" {
			floatProps = append(floatProps, p)
		}
	}
	if len(floatProps) == 0 {
		return
	}
	pn := s.api.pn
	pn("\nfunc (s *%s) UnmarshalJSON(data []byte) error {", s.GoName())
	pn("  type NoMethod %s", s.GoName()) // avoid infinite recursion
	pn("  var s1 struct {")
	// Hide the float64 fields of the schema with fields that correctly
	// unmarshal special values.
	for _, p := range floatProps {
		typ := "gensupport.JSONFloat64"
		if p.forcePointerType() {
			typ = "*" + typ
		}
		pn("%s %s `json:\"%s\"`", p.assignedGoName, typ, p.p.Name)
	}
	pn("    *NoMethod") // embed the schema
	pn("  }")
	// Set the schema value into the wrapper so its other fields are unmarshaled.
	pn("  s1.NoMethod = (*NoMethod)(s)")
	pn("  if err := json.Unmarshal(data, &s1); err != nil {")
	pn("    return err")
	pn("  }")
	// Copy each shadowing field into the field it shadows.
	for _, p := range floatProps {
		n := p.assignedGoName
		if p.forcePointerType() {
			pn("if s1.%s != nil { s.%s = (*float64)(s1.%s) }", n, n, n)
		} else {
			pn("s.%s = float64(s1.%s)", n, n)
		}
	}
	pn(" return nil")
	pn("}")
}

// isResponseType returns true for all types that are used as a response.
func (s *Schema) isResponseType() bool {
	return s.api.responseTypes["*"+s.goName]
}

// PopulateSchemas reads all the API types ("schemas") from the JSON file
// and converts them to *Schema instances, returning an identically
// keyed map, additionally containing subresources.  For instance,
//
// A resource "Foo" of type "object" with a property "bar", also of type
// "object" (an anonymous sub-resource), will get a synthetic API name
// of "Foo.bar".
//
// A resource "Foo" of type "array" with an "items" of type "object"
// will get a synthetic API name of "Foo.Item".
func (a *API) PopulateSchemas() {
	if a.schemas != nil {
		panic("")
	}
	a.schemas = make(map[string]*Schema)
	for name, ds := range a.doc.Schemas {
		s := &Schema{
			api:     a,
			apiName: name,
			typ:     ds,
		}
		a.schemas[name] = s
		err := s.populateSubSchemas()
		if err != nil {
			panicf("Error populating schema with API name %q: %v", name, err)
		}
	}
}

func (a *API) generateResource(r *disco.Resource) {
	pn := a.pn
	t := resourceGoType(r)
	pn(fmt.Sprintf("func New%s(s *%s) *%s {", t, a.ServiceType(), t))
	pn("rs := &%s{s : s}", t)
	for _, res := range r.Resources {
		pn("rs.%s = New%s(s)", resourceGoField(res, r), resourceGoType(res))
	}
	pn("return rs")
	pn("}")

	pn("\ntype %s struct {", t)
	pn(" s *%s", a.ServiceType())
	for _, res := range r.Resources {
		pn("\n\t%s\t*%s", resourceGoField(res, r), resourceGoType(res))
	}
	pn("}")

	for _, res := range r.Resources {
		a.generateResource(res)
	}
}

func (a *API) cacheResourceResponseTypes(r *disco.Resource) {
	for _, meth := range a.resourceMethods(r) {
		meth.cacheResponseTypes(a)
	}
	for _, res := range r.Resources {
		a.cacheResourceResponseTypes(res)
	}
}

func (a *API) generateResourceMethods(r *disco.Resource) {
	for _, meth := range a.resourceMethods(r) {
		meth.generateCode()
	}
	for _, res := range r.Resources {
		a.generateResourceMethods(res)
	}
}

func resourceGoField(r, parent *disco.Resource) string {
	// Avoid conflicts with method names.
	und := ""
	if parent != nil {
		for _, m := range parent.Methods {
			if m.Name == r.Name {
				und = "_"
				break
			}
		}
	}
	// Note: initialCap(r.Name + "_") doesn't work because initialCap calls depunct.
	return initialCap(r.Name) + und
}

func resourceGoType(r *disco.Resource) string {
	return initialCap(r.FullName + "Service")
}

func (a *API) resourceMethods(r *disco.Resource) []*Method {
	ms := []*Method{}
	for _, m := range r.Methods {
		ms = append(ms, &Method{
			api: a,
			r:   r,
			m:   m,
		})
	}
	return ms
}

type Method struct {
	api *API
	r   *disco.Resource // or nil if a API-level (top-level) method
	m   *disco.Method

	params []*Param // all Params, of each type, lazily set by first call of Params method.
}

func (m *Method) Id() string {
	return m.m.ID
}

func (m *Method) responseType() *Schema {
	return m.api.schemas[m.m.Response.RefSchema.Name]
}

func (m *Method) supportsMediaUpload() bool {
	return m.m.MediaUpload != nil
}

func (m *Method) mediaUploadPath() string {
	return m.m.MediaUpload.Protocols["simple"].Path
}

func (m *Method) supportsMediaDownload() bool {
	if m.supportsMediaUpload() {
		// storage.objects.insert claims support for download in
		// addition to upload but attempting to do so fails.
		// This situation doesn't apply to any other methods.
		return false
	}
	return m.m.SupportsMediaDownload
}

func (m *Method) supportsPaging() (*pageTokenGenerator, string, bool) {
	ptg := m.pageTokenGenerator()
	if ptg == nil {
		return nil, "", false
	}

	// Check that the response type has the next page token.
	s := m.responseType()
	if s == nil || s.typ.Kind != disco.StructKind {
		return nil, "", false
	}
	for _, prop := range s.properties() {
		if isPageTokenName(prop.p.Name) && prop.Type().Type == "string" {
			return ptg, prop.GoName(), true
		}
	}

	return nil, "", false
}

type pageTokenGenerator struct {
	isParam     bool   // is the page token a URL parameter?
	name        string // param or request field name
	requestName string // empty for URL param
}

func (p *pageTokenGenerator) genGet() string {
	if p.isParam {
		return fmt.Sprintf("c.urlParams_.Get(%q)", p.name)
	}
	return fmt.Sprintf("c.%s.%s", p.requestName, p.name)
}

func (p *pageTokenGenerator) genSet(valueExpr string) string {
	if p.isParam {
		return fmt.Sprintf("c.%s(%s)", initialCap(p.name), valueExpr)
	}
	return fmt.Sprintf("c.%s.%s = %s", p.requestName, p.name, valueExpr)
}

func (p *pageTokenGenerator) genDeferBody() string {
	if p.isParam {
		return p.genSet(p.genGet())
	}
	return fmt.Sprintf("func (pt string) { %s }(%s)", p.genSet("pt"), p.genGet())
}

// pageTokenGenerator returns a pageTokenGenerator that will generate code to
// get/set the page token for a subsequent page in the context of the generated
// Pages method. It returns nil if there is no page token.
func (m *Method) pageTokenGenerator() *pageTokenGenerator {
	matches := m.grepParams(func(p *Param) bool { return isPageTokenName(p.p.Name) })
	switch len(matches) {
	case 1:
		if matches[0].p.Required {
			// The page token is a required parameter (e.g. because there is
			// a separate API call to start an iteration), and so the relevant
			// call factory method takes the page token instead.
			return nil
		}
		n := matches[0].p.Name
		return &pageTokenGenerator{true, n, ""}

	case 0: // No URL parameter, but maybe a request field.
		if m.m.Request == nil {
			return nil
		}
		rs := m.m.Request
		if rs.RefSchema != nil {
			rs = rs.RefSchema
		}
		for _, p := range rs.Properties {
			if isPageTokenName(p.Name) {
				return &pageTokenGenerator{false, initialCap(p.Name), validGoIdentifer(strings.ToLower(rs.Name))}
			}
		}
		return nil

	default:
		panicf("too many page token parameters for method %s", m.m.Name)
		return nil
	}
}

func isPageTokenName(s string) bool {
	return s == "pageToken" || s == "nextPageToken"
}

func (m *Method) Params() []*Param {
	if m.params == nil {
		for _, p := range m.m.Parameters {
			m.params = append(m.params, &Param{
				method: m,
				p:      p,
			})
		}
	}
	return m.params
}

func (m *Method) grepParams(f func(*Param) bool) []*Param {
	matches := make([]*Param, 0)
	for _, param := range m.Params() {
		if f(param) {
			matches = append(matches, param)
		}
	}
	return matches
}

func (m *Method) NamedParam(name string) *Param {
	matches := m.grepParams(func(p *Param) bool {
		return p.p.Name == name
	})
	if len(matches) < 1 {
		log.Panicf("failed to find named parameter %q", name)
	}
	if len(matches) > 1 {
		log.Panicf("found multiple parameters for parameter name %q", name)
	}
	return matches[0]
}

func (m *Method) OptParams() []*Param {
	return m.grepParams(func(p *Param) bool {
		return !p.p.Required
	})
}

func (meth *Method) cacheResponseTypes(api *API) {
	if retType := responseType(api, meth.m); retType != "" && strings.HasPrefix(retType, "*") {
		api.responseTypes[retType] = true
	}
}

// convertMultiParams builds a []string temp variable from a slice
// of non-strings and returns the name of the temp variable.
func convertMultiParams(a *API, param string) string {
	a.pn(" var %v_ []string", param)
	a.pn(" for _, v := range %v {", param)
	a.pn("  %v_ = append(%v_, fmt.Sprint(v))", param, param)
	a.pn(" }")
	return param + "_"
}

func (meth *Method) generateCode() {
	res := meth.r // may be nil if a top-level method
	a := meth.api
	p, pn := a.p, a.pn

	pn("\n// method id %q:", meth.Id())

	retType := responseType(a, meth.m)
	retTypeComma := retType
	if retTypeComma != "" {
		retTypeComma += ", "
	}

	args := meth.NewArguments()
	methodName := initialCap(meth.m.Name)
	prefix := ""
	if res != nil {
		prefix = initialCap(res.FullName)
	}
	callName := a.GetName(prefix + methodName + "Call")

	pn("\ntype %s struct {", callName)
	pn(" s *%s", a.ServiceType())
	for _, arg := range args.l {
		if arg.location != "query" {
			pn(" %s %s", arg.goname, arg.gotype)
		}
	}
	pn(" urlParams_ gensupport.URLParams")
	httpMethod := meth.m.HTTPMethod
	if httpMethod == "GET" {
		pn(" ifNoneMatch_ string")
	}

	if meth.supportsMediaUpload() {
		pn(" mediaInfo_ *gensupport.MediaInfo")
	}
	pn(" ctx_ context.Context")
	pn(" header_ http.Header")
	pn("}")

	p("\n%s", asComment("", methodName+": "+meth.m.Description))
	if res != nil {
		if url := canonicalDocsURL[fmt.Sprintf("%v%v/%v", docsLink, res.Name, meth.m.Name)]; url != "" {
			pn("// For details, see %v", url)
		}
	}

	var servicePtr string
	if res == nil {
		pn("func (s *Service) %s(%s) *%s {", methodName, args, callName)
		servicePtr = "s"
	} else {
		pn("func (r *%s) %s(%s) *%s {", resourceGoType(res), methodName, args, callName)
		servicePtr = "r.s"
	}

	pn(" c := &%s{s: %s, urlParams_: make(gensupport.URLParams)}", callName, servicePtr)
	for _, arg := range args.l {
		// TODO(gmlewis): clean up and consolidate this section.
		// See: https://code-review.googlesource.com/#/c/3520/18/google-api-go-generator/gen.go
		if arg.location == "query" {
			switch arg.gotype {
			case "[]string":
				pn(" c.urlParams_.SetMulti(%q, append([]string{}, %v...))", arg.apiname, arg.goname)
			case "string":
				pn(" c.urlParams_.Set(%q, %v)", arg.apiname, arg.goname)
			default:
				if strings.HasPrefix(arg.gotype, "[]") {
					tmpVar := convertMultiParams(a, arg.goname)
					pn(" c.urlParams_.SetMulti(%q, %v)", arg.apiname, tmpVar)
				} else {
					pn(" c.urlParams_.Set(%q, fmt.Sprint(%v))", arg.apiname, arg.goname)
				}
			}
			continue
		}
		if arg.gotype == "[]string" {
			pn(" c.%s = append([]string{}, %s...)", arg.goname, arg.goname) // Make a copy of the []string.
			continue
		}
		pn(" c.%s = %s", arg.goname, arg.goname)
	}
	pn(" return c")
	pn("}")

	for _, opt := range meth.OptParams() {
		if opt.p.Location != "query" {
			panicf("optional parameter has unsupported location %q", opt.p.Location)
		}
		setter := initialCap(opt.p.Name)
		des := opt.p.Description
		des = strings.Replace(des, "Optional.", "", 1)
		des = strings.TrimSpace(des)
		p("\n%s", asComment("", fmt.Sprintf("%s sets the optional parameter %q: %s", setter, opt.p.Name, des)))
		addFieldValueComments(p, opt, "", true)
		np := new(namePool)
		np.Get("c") // take the receiver's name
		paramName := np.Get(validGoIdentifer(opt.p.Name))
		typePrefix := ""
		if opt.p.Repeated {
			typePrefix = "..."
		}
		pn("func (c *%s) %s(%s %s%s) *%s {", callName, setter, paramName, typePrefix, opt.GoType(), callName)
		if opt.p.Repeated {
			if opt.GoType() == "string" {
				pn("c.urlParams_.SetMulti(%q, append([]string{}, %v...))", opt.p.Name, paramName)
			} else {
				tmpVar := convertMultiParams(a, paramName)
				pn(" c.urlParams_.SetMulti(%q, %v)", opt.p.Name, tmpVar)
			}
		} else {
			if opt.GoType() == "string" {
				pn("c.urlParams_.Set(%q, %v)", opt.p.Name, paramName)
			} else {
				pn("c.urlParams_.Set(%q, fmt.Sprint(%v))", opt.p.Name, paramName)
			}
		}
		pn("return c")
		pn("}")
	}

	if meth.supportsMediaUpload() {
		comment := "Media specifies the media to upload in one or more chunks. " +
			"The chunk size may be controlled by supplying a MediaOption generated by googleapi.ChunkSize. " +
			"The chunk size defaults to googleapi.DefaultUploadChunkSize." +
			"The Content-Type header used in the upload request will be determined by sniffing the contents of r, " +
			"unless a MediaOption generated by googleapi.ContentType is supplied." +
			"\nAt most one of Media and ResumableMedia may be set."
		// TODO(mcgreevy): Ensure that r is always closed before Do returns, and document this.
		// See comments on https://code-review.googlesource.com/#/c/3970/
		p("\n%s", asComment("", comment))
		pn("func (c *%s) Media(r io.Reader, options ...googleapi.MediaOption) *%s {", callName, callName)
		// We check if the body arg, if any, has a content type and apply it here.
		// In practice, this only happens for the storage API today.
		// TODO(djd): check if we can cope with the developer setting the body's Content-Type field
		// after they've made this call.
		if ba := args.bodyArg(); ba != nil {
			if ba.schema.HasContentType() {
				pn("  if ct := c.%s.ContentType; ct != \"\" {", ba.goname)
				pn("   options = append([]googleapi.MediaOption{googleapi.ContentType(ct)}, options...)")
				pn("  }")
			}
		}
		pn(" c.mediaInfo_ = gensupport.NewInfoFromMedia(r, options)")
		pn(" return c")
		pn("}")
		comment = "ResumableMedia specifies the media to upload in chunks and can be canceled with ctx. " +
			"\n\nDeprecated: use Media instead." +
			"\n\nAt most one of Media and ResumableMedia may be set. " +
			`mediaType identifies the MIME media type of the upload, such as "image/png". ` +
			`If mediaType is "", it will be auto-detected. ` +
			`The provided ctx will supersede any context previously provided to ` +
			`the Context method.`
		p("\n%s", asComment("", comment))
		pn("func (c *%s) ResumableMedia(ctx context.Context, r io.ReaderAt, size int64, mediaType string) *%s {", callName, callName)
		pn(" c.ctx_ = ctx")
		pn(" c.mediaInfo_ = gensupport.NewInfoFromResumableMedia(r, size, mediaType)")
		pn(" return c")
		pn("}")
		comment = "ProgressUpdater provides a callback function that will be called after every chunk. " +
			"It should be a low-latency function in order to not slow down the upload operation. " +
			"This should only be called when using ResumableMedia (as opposed to Media)."
		p("\n%s", asComment("", comment))
		pn("func (c *%s) ProgressUpdater(pu googleapi.ProgressUpdater) *%s {", callName, callName)
		pn(`c.mediaInfo_.SetProgressUpdater(pu)`)
		pn("return c")
		pn("}")
	}

	comment := "Fields allows partial responses to be retrieved. " +
		"See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse " +
		"for more information."
	p("\n%s", asComment("", comment))
	pn("func (c *%s) Fields(s ...googleapi.Field) *%s {", callName, callName)
	pn(`c.urlParams_.Set("fields", googleapi.CombineFields(s))`)
	pn("return c")
	pn("}")
	if httpMethod == "GET" {
		// Note that non-GET responses are excluded from supporting If-None-Match.
		// See https://github.com/google/google-api-go-client/issues/107 for more info.
		comment := "IfNoneMatch sets the optional parameter which makes the operation fail if " +
			"the object's ETag matches the given value. This is useful for getting updates " +
			"only after the object has changed since the last request. " +
			"Use googleapi.IsNotModified to check whether the response error from Do " +
			"is the result of In-None-Match."
		p("\n%s", asComment("", comment))
		pn("func (c *%s) IfNoneMatch(entityTag string) *%s {", callName, callName)
		pn(" c.ifNoneMatch_ = entityTag")
		pn(" return c")
		pn("}")
	}

	doMethod := "Do method"
	if meth.supportsMediaDownload() {
		doMethod = "Do and Download methods"
	}
	commentFmtStr := "Context sets the context to be used in this call's %s. " +
		"Any pending HTTP request will be aborted if the provided context is canceled."
	comment = fmt.Sprintf(commentFmtStr, doMethod)
	p("\n%s", asComment("", comment))
	if meth.supportsMediaUpload() {
		comment = "This context will supersede any context previously provided to " +
			"the ResumableMedia method."
		p("%s", asComment("", comment))
	}
	pn("func (c *%s) Context(ctx context.Context) *%s {", callName, callName)
	pn(`c.ctx_ = ctx`)
	pn("return c")
	pn("}")

	comment = "Header returns an http.Header that can be modified by the caller to add " +
		"HTTP headers to the request."
	p("\n%s", asComment("", comment))
	pn("func (c *%s) Header() http.Header {", callName)
	pn(" if c.header_ == nil {")
	pn("  c.header_ = make(http.Header)")
	pn(" }")
	pn(" return c.header_")
	pn("}")

	pn("\nfunc (c *%s) doRequest(alt string) (*http.Response, error) {", callName)
	pn(`reqHeaders := make(http.Header)`)
	pn("for k, v := range c.header_ {")
	pn(" reqHeaders[k] = v")
	pn("}")
	pn(`reqHeaders.Set("User-Agent",c.s.userAgent())`)
	if httpMethod == "GET" {
		pn(`if c.ifNoneMatch_ != "" {`)
		pn(` reqHeaders.Set("If-None-Match",  c.ifNoneMatch_)`)
		pn("}")
	}
	pn("var body io.Reader = nil")
	if ba := args.bodyArg(); ba != nil && httpMethod != "GET" {
		if meth.m.ID == "ml.projects.predict" {
			// Skip JSONReader for APIs that require clients to pass in JSON already.
			pn("body = strings.NewReader(c.%s.HttpBody.Data)", ba.goname)
		} else {
			style := "WithoutDataWrapper"
			if a.needsDataWrapper() {
				style = "WithDataWrapper"
			}
			pn("body, err := googleapi.%s.JSONReader(c.%s)", style, ba.goname)
			pn("if err != nil { return nil, err }")
		}

		pn(`reqHeaders.Set("Content-Type", "application/json")`)
	}
	pn(`c.urlParams_.Set("alt", alt)`)
	pn(`c.urlParams_.Set("prettyPrint", "false")`)

	pn("urls := googleapi.ResolveRelative(c.s.BasePath, %q)", meth.m.Path)
	if meth.supportsMediaUpload() {
		pn("if c.mediaInfo_ != nil {")
		// Hack guess, since we get a 404 otherwise:
		//pn("urls = googleapi.ResolveRelative(%q, %q)", a.apiBaseURL(), meth.mediaUploadPath())
		// Further hack.  Discovery doc is wrong?
		pn("  urls = strings.Replace(urls, %q, %q, 1)", "https://www.googleapis.com/", "https://www.googleapis.com/upload/")
		pn(`  c.urlParams_.Set("uploadType", c.mediaInfo_.UploadType())`)
		pn("}")

		pn("if body == nil {")
		pn(" body = new(bytes.Buffer)")
		pn(` reqHeaders.Set("Content-Type", "application/json")`)
		pn("}")
		pn("body, getBody, cleanup := c.mediaInfo_.UploadRequest(reqHeaders, body)")
		pn("defer cleanup()")
	}
	pn("urls += \"?\" + c.urlParams_.Encode()")
	pn("req, err := http.NewRequest(%q, urls, body)", httpMethod)
	pn("if err != nil { return nil, err }")
	pn("req.Header = reqHeaders")
	if meth.supportsMediaUpload() {
		pn("gensupport.SetGetBody(req, getBody)")
	}

	// Replace param values after NewRequest to avoid reencoding them.
	// E.g. Cloud Storage API requires '%2F' in entity param to be kept, but url.Parse replaces it with '/'.
	argsForLocation := args.forLocation("path")
	if len(argsForLocation) > 0 {
		pn(`googleapi.Expand(req.URL, map[string]string{`)
		for _, arg := range argsForLocation {
			pn(`"%s": %s,`, arg.apiname, arg.exprAsString("c."))
		}
		pn(`})`)
	}

	pn("return gensupport.SendRequest(c.ctx_, c.s.client, req)")
	pn("}")

	if meth.supportsMediaDownload() {
		pn("\n// Download fetches the API endpoint's \"media\" value, instead of the normal")
		pn("// API response value. If the returned error is nil, the Response is guaranteed to")
		pn("// have a 2xx status code. Callers must close the Response.Body as usual.")
		pn("func (c *%s) Download(opts ...googleapi.CallOption) (*http.Response, error) {", callName)
		pn(`gensupport.SetOptions(c.urlParams_, opts...)`)
		pn(`res, err := c.doRequest("media")`)
		pn("if err != nil { return nil, err }")
		pn("if err := googleapi.CheckMediaResponse(res); err != nil {")
		pn("res.Body.Close()")
		pn("return nil, err")
		pn("}")
		pn("return res, nil")
		pn("}")
	}

	mapRetType := strings.HasPrefix(retTypeComma, "map[")
	pn("\n// Do executes the %q call.", meth.m.ID)
	if retTypeComma != "" && !mapRetType {
		commentFmtStr := "Exactly one of %v or error will be non-nil. " +
			"Any non-2xx status code is an error. " +
			"Response headers are in either %v.ServerResponse.Header " +
			"or (if a response was returned at all) in error.(*googleapi.Error).Header. " +
			"Use googleapi.IsNotModified to check whether the returned error was because " +
			"http.StatusNotModified was returned."
		comment := fmt.Sprintf(commentFmtStr, retType, retType)
		p("%s", asComment("", comment))
	}
	pn("func (c *%s) Do(opts ...googleapi.CallOption) (%serror) {", callName, retTypeComma)
	nilRet := ""
	if retTypeComma != "" {
		nilRet = "nil, "
	}
	pn(`gensupport.SetOptions(c.urlParams_, opts...)`)
	pn(`res, err := c.doRequest("json")`)

	if retTypeComma != "" && !mapRetType {
		pn("if res != nil && res.StatusCode == http.StatusNotModified {")
		pn(" if res.Body != nil { res.Body.Close() }")
		pn(" return nil, &googleapi.Error{")
		pn("  Code: res.StatusCode,")
		pn("  Header: res.Header,")
		pn(" }")
		pn("}")
	}
	pn("if err != nil { return %serr }", nilRet)
	pn("defer googleapi.CloseBody(res)")
	pn("if err := googleapi.CheckResponse(res); err != nil { return %serr }", nilRet)
	if meth.supportsMediaUpload() {
		pn(`rx := c.mediaInfo_.ResumableUpload(res.Header.Get("Location"))`)
		pn("if rx != nil {")
		pn(" rx.Client = c.s.client")
		pn(" rx.UserAgent = c.s.userAgent()")
		pn(" ctx := c.ctx_")
		pn(" if ctx == nil {")
		// TODO(mcgreevy): Require context when calling Media, or Do.
		pn("  ctx = context.TODO()")
		pn(" }")
		pn(" res, err = rx.Upload(ctx)")
		pn(" if err != nil { return %serr }", nilRet)
		pn(" defer res.Body.Close()")
		pn(" if err := googleapi.CheckResponse(res); err != nil { return %serr }", nilRet)
		pn("}")
	}
	if retTypeComma == "" {
		pn("return nil")
	} else {
		if mapRetType {
			pn("var ret %s", responseType(a, meth.m))
		} else {
			pn("ret := &%s{", responseTypeLiteral(a, meth.m))
			pn(" ServerResponse: googleapi.ServerResponse{")
			pn("  Header: res.Header,")
			pn("  HTTPStatusCode: res.StatusCode,")
			pn(" },")
			pn("}")
		}
		if a.needsDataWrapper() {
			pn("target := &struct {")
			pn("  Data %s `json:\"data\"`", responseType(a, meth.m))
			pn("}{ret}")
		} else {
			pn("target := &ret")
		}

		if meth.m.ID == "ml.projects.predict" {
			pn("var b bytes.Buffer")
			pn("if _, err := io.Copy(&b, res.Body); err != nil { return nil, err }")
			pn("if err := res.Body.Close(); err != nil { return nil, err }")
			pn("if err := json.NewDecoder(bytes.NewReader(b.Bytes())).Decode(target); err != nil { return nil, err }")
			pn("ret.Data = b.String()")
		} else {
			pn("if err := gensupport.DecodeResponse(target, res); err != nil { return nil, err }")
		}
		pn("return ret, nil")
	}

	bs, err := json.MarshalIndent(meth.m.JSONMap, "\t// ", "  ")
	if err != nil {
		panic(err)
	}
	pn("// %s\n", string(bs))
	pn("}")

	if ptg, rname, ok := meth.supportsPaging(); ok {
		// We can assume retType is non-empty.
		pn("")
		pn("// Pages invokes f for each page of results.")
		pn("// A non-nil error returned from f will halt the iteration.")
		pn("// The provided context supersedes any context provided to the Context method.")
		pn("func (c *%s) Pages(ctx context.Context, f func(%s) error) error {", callName, retType)
		pn(" c.ctx_ = ctx")
		pn(` defer %s  // reset paging to original point`, ptg.genDeferBody())
		pn(" for {")
		pn("  x, err := c.Do()")
		pn("  if err != nil { return err }")
		pn("  if err := f(x); err != nil { return err }")
		pn(`  if x.%s == "" { return nil }`, rname)
		pn(ptg.genSet("x." + rname))
		pn(" }")
		pn("}")
	}
}

// A Field provides methods that describe the characteristics of a Param or Property.
type Field interface {
	Default() string
	Enum() ([]string, bool)
	EnumDescriptions() []string
	UnfortunateDefault() bool
}

type Param struct {
	method        *Method
	p             *disco.Parameter
	callFieldName string // empty means to use the default
}

func (p *Param) Default() string {
	return p.p.Default
}

func (p *Param) Enum() ([]string, bool) {
	if e := p.p.Enums; e != nil {
		return e, true
	}
	return nil, false
}

func (p *Param) EnumDescriptions() []string {
	return p.p.EnumDescriptions
}

func (p *Param) UnfortunateDefault() bool {
	// We do not do anything special for Params with unfortunate defaults.
	return false
}

func (p *Param) GoType() string {
	typ, format := p.p.Type, p.p.Format
	if typ == "string" && strings.Contains(format, "int") && p.p.Location != "query" {
		panic("unexpected int parameter encoded as string, not in query: " + p.p.Name)
	}
	t, ok := simpleTypeConvert(typ, format)
	if !ok {
		panic("failed to convert parameter type " + fmt.Sprintf("type=%q, format=%q", typ, format))
	}
	return t
}

// goCallFieldName returns the name of this parameter's field in a
// method's "Call" struct.
func (p *Param) goCallFieldName() string {
	if p.callFieldName != "" {
		return p.callFieldName
	}
	return validGoIdentifer(p.p.Name)
}

// APIMethods returns top-level ("API-level") methods. They don't have an associated resource.
func (a *API) APIMethods() []*Method {
	meths := []*Method{}
	for _, m := range a.doc.Methods {
		meths = append(meths, &Method{
			api: a,
			r:   nil, // to be explicit
			m:   m,
		})
	}
	return meths
}

func resolveRelative(basestr, relstr string) string {
	u, err := url.Parse(basestr)
	if err != nil {
		panicf("Error parsing base URL %q: %v", basestr, err)
	}
	rel, err := url.Parse(relstr)
	if err != nil {
		panicf("Error parsing relative URL %q: %v", relstr, err)
	}
	u = u.ResolveReference(rel)
	return u.String()
}

func (meth *Method) NewArguments() *arguments {
	args := &arguments{
		method: meth,
		m:      make(map[string]*argument),
	}
	pnames := meth.m.ParameterOrder
	if len(pnames) == 0 {
		// No parameterOrder; collect required parameters and sort by name.
		for _, reqParam := range meth.grepParams(func(p *Param) bool { return p.p.Required }) {
			pnames = append(pnames, reqParam.p.Name)
		}
		sort.Strings(pnames)
	}
	for _, pname := range pnames {
		arg := meth.NewArg(pname, meth.NamedParam(pname))
		args.AddArg(arg)
	}
	if rs := meth.m.Request; rs != nil {
		args.AddArg(meth.NewBodyArg(rs))
	}
	return args
}

func (meth *Method) NewBodyArg(ds *disco.Schema) *argument {
	s := meth.api.schemaNamed(ds.RefSchema.Name)
	return &argument{
		goname:   validGoIdentifer(strings.ToLower(ds.Ref)),
		apiname:  "REQUEST",
		gotype:   "*" + s.GoName(),
		apitype:  ds.Ref,
		location: "body",
		schema:   s,
	}
}

func (meth *Method) NewArg(apiname string, p *Param) *argument {
	apitype := p.p.Type
	des := p.p.Description
	goname := validGoIdentifer(apiname) // but might be changed later, if conflicts
	if strings.Contains(des, "identifier") && !strings.HasSuffix(strings.ToLower(goname), "id") {
		goname += "id" // yay
		p.callFieldName = goname
	}
	gotype := mustSimpleTypeConvert(apitype, p.p.Format)
	if p.p.Repeated {
		gotype = "[]" + gotype
	}
	return &argument{
		apiname:  apiname,
		apitype:  apitype,
		goname:   goname,
		gotype:   gotype,
		location: p.p.Location,
	}
}

type argument struct {
	method           *Method
	schema           *Schema // Set if location == "body".
	apiname, apitype string
	goname, gotype   string
	location         string // "path", "query", "body"
}

func (a *argument) String() string {
	return a.goname + " " + a.gotype
}

func (a *argument) exprAsString(prefix string) string {
	switch a.gotype {
	case "[]string":
		log.Printf("TODO(bradfitz): only including the first parameter in path query.")
		return prefix + a.goname + `[0]`
	case "string":
		return prefix + a.goname
	case "integer", "int64":
		return "strconv.FormatInt(" + prefix + a.goname + ", 10)"
	case "uint64":
		return "strconv.FormatUint(" + prefix + a.goname + ", 10)"
	case "bool":
		return "strconv.FormatBool(" + prefix + a.goname + ")"
	}
	log.Panicf("unknown type: apitype=%q, gotype=%q", a.apitype, a.gotype)
	return ""
}

// arguments are the arguments that a method takes
type arguments struct {
	l      []*argument
	m      map[string]*argument
	method *Method
}

func (args *arguments) forLocation(loc string) []*argument {
	matches := make([]*argument, 0)
	for _, arg := range args.l {
		if arg.location == loc {
			matches = append(matches, arg)
		}
	}
	return matches
}

func (args *arguments) bodyArg() *argument {
	for _, arg := range args.l {
		if arg.location == "body" {
			return arg
		}
	}
	return nil
}

func (args *arguments) AddArg(arg *argument) {
	n := 1
	oname := arg.goname
	for {
		_, present := args.m[arg.goname]
		if !present {
			args.m[arg.goname] = arg
			args.l = append(args.l, arg)
			return
		}
		n++
		arg.goname = fmt.Sprintf("%s%d", oname, n)
	}
}

func (a *arguments) String() string {
	var buf bytes.Buffer
	for i, arg := range a.l {
		if i != 0 {
			buf.Write([]byte(", "))
		}
		buf.Write([]byte(arg.String()))
	}
	return buf.String()
}

var urlRE = regexp.MustCompile(`^http\S+$`)

func asComment(pfx, c string) string {
	var buf bytes.Buffer
	const maxLen = 70
	r := strings.NewReplacer(
		"\n", "\n"+pfx+"// ",
		"`\"", `"`,
		"\"`", `"`,
	)
	for len(c) > 0 {
		line := c
		if len(line) < maxLen {
			fmt.Fprintf(&buf, "%s// %s\n", pfx, r.Replace(line))
			break
		}
		// Don't break URLs.
		if !urlRE.MatchString(line[:maxLen]) {
			line = line[:maxLen]
		}
		si := strings.LastIndex(line, " ")
		if nl := strings.Index(line, "\n"); nl != -1 && nl < si {
			si = nl
		}
		if si != -1 {
			line = line[:si]
		}
		fmt.Fprintf(&buf, "%s// %s\n", pfx, r.Replace(line))
		c = c[len(line):]
		if si != -1 {
			c = c[1:]
		}
	}
	return buf.String()
}

func simpleTypeConvert(apiType, format string) (gotype string, ok bool) {
	// From http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.1
	switch apiType {
	case "boolean":
		gotype = "bool"
	case "string":
		gotype = "string"
		switch format {
		case "int64", "uint64", "int32", "uint32":
			gotype = format
		}
	case "number":
		gotype = "float64"
	case "integer":
		gotype = "int64"
	case "any":
		gotype = "interface{}"
	}
	return gotype, gotype != ""
}

func mustSimpleTypeConvert(apiType, format string) string {
	if gotype, ok := simpleTypeConvert(apiType, format); ok {
		return gotype
	}
	panic(fmt.Sprintf("failed to simpleTypeConvert(%q, %q)", apiType, format))
}

func responseType(api *API, m *disco.Method) string {
	if m.Response == nil {
		return ""
	}
	ref := m.Response.Ref
	if ref != "" {
		if s := api.schemas[ref]; s != nil {
			return s.GoReturnType()
		}
		return "*" + ref
	}
	return ""
}

// Strips the leading '*' from a type name so that it can be used to create a literal.
func responseTypeLiteral(api *API, m *disco.Method) string {
	v := responseType(api, m)
	if strings.HasPrefix(v, "*") {
		return v[1:]
	}
	return v
}

// initialCap returns the identifier with a leading capital letter.
// it also maps "foo-bar" to "FooBar".
func initialCap(ident string) string {
	if ident == "" {
		panic("blank identifier")
	}
	return depunct(ident, true)
}

func validGoIdentifer(ident string) string {
	id := depunct(ident, false)
	switch id {
	case "break", "default", "func", "interface", "select",
		"case", "defer", "go", "map", "struct",
		"chan", "else", "goto", "package", "switch",
		"const", "fallthrough", "if", "range", "type",
		"continue", "for", "import", "return", "var":
		return id + "_"
	}
	return id
}

// depunct removes '-', '.', '$', '/', '_' from identifers, making the
// following character uppercase. Multiple '_' are preserved.
func depunct(ident string, needCap bool) string {
	var buf bytes.Buffer
	preserve_ := false
	for i, c := range ident {
		if c == '_' {
			if preserve_ || strings.HasPrefix(ident[i:], "__") {
				preserve_ = true
			} else {
				needCap = true
				continue
			}
		} else {
			preserve_ = false
		}
		if c == '-' || c == '.' || c == '$' || c == '/' {
			needCap = true
			continue
		}
		if needCap {
			c = unicode.ToUpper(c)
			needCap = false
		}
		buf.WriteByte(byte(c))
	}
	return buf.String()

}

func addFieldValueComments(p func(format string, args ...interface{}), field Field, indent string, blankLine bool) {
	var lines []string

	if enum, ok := field.Enum(); ok {
		desc := field.EnumDescriptions()
		lines = append(lines, asComment(indent, "Possible values:"))
		defval := field.Default()
		for i, v := range enum {
			more := ""
			if v == defval {
				more = " (default)"
			}
			if len(desc) > i && desc[i] != "" {
				more = more + " - " + desc[i]
			}
			lines = append(lines, asComment(indent, `  "`+v+`"`+more))
		}
	} else if field.UnfortunateDefault() {
		lines = append(lines, asComment("\t", fmt.Sprintf("Default: %s", field.Default())))
	}
	if blankLine && len(lines) > 0 {
		p(indent + "//\n")
	}
	for _, l := range lines {
		p("%s", l)
	}
}
