code: func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {
  	var buf bytes.Buffer
  	buf.WriteString(c.Endpoint.AuthURL)
  	v := url.Values{
  		"response_type": {"code"},
  		"client_id":     {c.ClientID},
  	}
  	if c.RedirectURL != "" {
  		v.Set("redirect_uri", c.RedirectURL)
  	}
  	if len(c.Scopes) > 0 {
  		v.Set("scope", strings.Join(c.Scopes, " "))
  	}
  	if state != "" {
  		// TODO(light): Docs say never to omit state; don't allow empty.
  		v.Set("state", state)
  	}
  	for _, opt := range opts {
  		opt.setValue(v)
  	}
  	if strings.Contains(c.Endpoint.AuthURL, "?") {
  		buf.WriteByte('&')
  	} else {
  		buf.WriteByte('?')
  	}
  	buf.WriteString(v.Encode())
  	return buf.String()
  }
docs: // AuthCodeURL returns a URL to OAuth 2.0 provider's consent page
  // that asks for permissions for the required scopes explicitly.
  //
  // State is a token to protect the user from CSRF attacks. You must
  // always provide a non-empty string and validate that it matches the
  // the state query parameter on your redirect callback.
  // See http://tools.ietf.org/html/rfc6749#section-10.12 for more info.
  //
  // Opts may include AccessTypeOnline or AccessTypeOffline, as well
  // as ApprovalForce.
  // It can also be used to pass the PKCE challenge.
  // See https://www.oauth.com/oauth2-servers/pkce/ for more info.